---
output:
  pdf_document:
    fig_caption: yes
    fig_crop: yes
    keep_tex: yes
    number_sections: true
  word_document: default
header-includes:
   - \usepackage{caption,booktabs,longtable,pdfpages,rotating,graphicx,footmisc,float,tikz,amsthm,afterpage,setspace,minitoc,lscape,multirow}
   - \captionsetup{width=5in}
   - \setlength\parindent{24pt}  
   - \bibliographystyle{apsr}
   - \renewcommand{\footnotesize}{\fontsize{10pt}{10pt}\selectfont}
   - \renewcommand{\footnotelayout}{\setstretch{1.5}}
   - \setlength{\footnotesep}{\baselineskip}   
   - \captionsetup{width=6in}
   - \renewcommand \thepart{}
   - \renewcommand \partname{} 
   - \renewcommand{\thesection}{\Alph{section}}
   - \newcommand{\blandscape}{\begin{landscape}}
   - \newcommand{\elandscape}{\end{landscape}}
   - \usepackage[margin=1in]{geometry}
   - \floatplacement{figure}{H} 
fontsize: 11pt
---

\doparttoc 
\faketableofcontents

\clearpage

\setcounter{page}{0}
\pagenumbering{arabic}
\setcounter{page}{21}

```{r include=F, warning=F, message=F}
# load packages
  source("../helper-packages.R")

# increase memory limit
  memory.limit(size = 500000)

# keep aux files
  options(tinytex.clean = FALSE)

# load world map
  world_maps_raw <- 
    st_read("../../00-data/raw-data/world-dashmaps/world-map-2/ne_110m_admin_0_countries.shp")
  
# load long data
  analysis_df <- 
    readRDS("../../00-data/cleaned-data/analysis_df.rds")
   
# load cleaned nelda dataset
  nelda_full_raw <- 
    readRDS("../../00-data/cleaned-data/x-1-nelda.rds")

# subset to religious outgroups      
  analysis_df_outgroups <- 
    analysis_df %>%
    filter(
      # keep only respondents answering questions about religious outgroups
      resp_is_outgroup == 1 & 
      # keep only outcomes related to religious intolerance  
      !qinfo_type_group %in% c("General trust", "Religiosity") &
      # for primary analyses, only keep rows with non-missing outcomes (this matters for weights)  
      resp_response_na == 0)
   
# subset to general trust      
  analysis_df_gentrust <- 
    analysis_df %>%
    filter(
      # keep only outcomes related to generalized social trust 
      qinfo_type_group %in% c("General trust") & 
      # keep only non-missing outcomes  
      resp_response_na == 0)
   
# subset to religiosity      
  analysis_df_religiosity <- 
    analysis_df %>%
    filter(
      # keep only outcomes related to religiosity 
      qinfo_type_group %in% c("Religiosity") &
      # keep only non-missing outcomes  
      resp_response_na == 0)
  
# subset to outgroups dataframe but including those       
  analysis_df_has_and_doesnt_have_religion <- 
    analysis_df %>%
    # only one record per respondent
    distinct(resp_id, .keep_all = T) %>%
    filter(
      # keep only outcomes related to religiosity 
      !qinfo_type_group %in% c("General trust", "Religiosity"))  

# outgroups dataframe but unique respondents   
  analysis_df_outgroups_unique_rs <- 
    analysis_df_outgroups %>% 
    distinct(resp_id, .keep_all = T)
  
# religious outgroups dataframe for attrition analysis (includes those who do not reply to intolerance question in the survey)      
  analysis_df_outgroups_attrition <- 
    analysis_df %>%
    filter(
      # keep only respondents answering questions about religious outgroups
      resp_is_outgroup == 1 & 
      # keep only outcomes related to religious intolerance  
      !qinfo_type_group %in% c("General trust", "Religiosity"))
  
## switches  
  # switch for compiling main figures from scratch 
    figures_from_scratch <- F
  
  # switch for compiling loess figures from scratch 
    loess_from_scratch <- F
    
  # switch for running balance tests from scratch  
    balance_from_scratch <- F
    
  # switch for running specification curve analyses from scratch  
    speccurve_from_scratch <- F
   
  # switch for running hte models from scratch  
    hte_mods_from_scratch <- F
    
  # switch for running hte forest plot from scratch   
    hte_figs_from_scratch <- F
```

\clearpage

<!-- figuse 1: descriptives -->

```{r}
######## plot A: 30 countries with highest shares of religious intolerance #########

  if(isTRUE(figures_from_scratch)) {
  
  # create output
     out <- 
        analysis_df_outgroups %>% 
        mutate(resp_survey_round = paste(resp_source, resp_round)) %>% 
        group_by(resp_country_common) %>% 
          summarise(
            mean_prjudice = mean(resp_soc_dist_bin_recode, na.rm = T),
            nobs = sum(!is.na(resp_soc_dist_bin_recode)),
            n_unique_rounds = length(unique(resp_survey_round)),
            date_range_min = paste0("'", str_sub(year(min(resp_main_date, na.rm = T)),-2,-1)),
            date_range_max = paste0("'", str_sub(year(max(resp_main_date, na.rm = T)),-2,-1)),
            region = unique(region)) %>% 
          mutate(
            nobs_surveys = str_trim(paste0(format(nobs, big.mark=","), " (", n_unique_rounds, ")")),
            date_range = 
              case_when(
                date_range_min == date_range_max ~ as.character(date_range_min),
                TRUE ~ paste0(date_range_min, "-", date_range_max))) %>%
          arrange(desc(mean_prjudice)) %>% 
          select(-c(date_range_min, date_range_max))
  
  # plot
  ## set breaks and labels
    breaks <- append(10*0:8, c(90, 100, 110, 120))
    ticklabels <- c('0', '10', '20', '30', '40', '50', '60', '70', '80', 'Years', '','N (surveys)', '')
  
  ## generate the plot
    p1 <- 
      ggplot(data = out %>% slice(1:30), aes(y = reorder(resp_country_common, mean_prjudice), x = 100 * mean_prjudice, fill = region)) +
      geom_bar(stat = "identity")+
      theme_minimal() +
      ylab(element_blank()) +
      xlab("% expressing intolerant attitude toward religious outgroup") + 
      theme(axis.title = element_text(size=16)) +
      geom_text(aes(label = paste0(sprintf("%.01f", mean_prjudice * 100), "%")), size = 3.5, hjust = -0.1) +
      geom_text(aes(x = 90, label = date_range), size = 3.5) +
      geom_text(aes(x = 110,label = nobs_surveys), size = 3.5) +
      scale_fill_brewer(palette = "Set2") +
      scale_x_continuous(
        limits = c(0, 130), 
        expand = c(0,0), 
        breaks = breaks, labels = ticklabels, 
        sec.axis = sec_axis(~ . * 1, breaks = breaks, labels = ticklabels)) + 
      guides(fill = guide_legend(override.aes = list(size = 4.5), nrow = 3, byrow = TRUE)) +
      theme(
        text = element_text(size = 15),
        legend.title = element_blank(),
        legend.position = "bottom",
        legend.justification = c(0, 0),
        legend.direction = 'horizontal',
        legend.spacing.x = unit(0, 'cm'),
        panel.grid.minor = element_blank(),
        panel.grid.major = element_blank())
    
  # save to pdf file
    pdf("_temp_figs/descriptives_1.pdf", width = 8, height = 10)
    p1
    dev.off()

######## plot B: map of intolerance #########
    
  # collapse country means
    countries_avgs <-
      analysis_df_outgroups %>%
      group_by(resp_country_common) %>%
        summarise(
          n_obs = n(),
          df_prejudice_all = mean(resp_soc_dist_bin_recode, na.rm = T)) %>%
      ungroup() %>%
      mutate(
          df_prejudice_all_cut =
            cut(df_prejudice_all, quantile(df_prejudice_all, 0:3/3, na.rm = T),
                labels = c("Least", "Moderate", "Most intolerance")))
  
  # merge in map data
    world_map_clean <- 
      world_maps_raw %>% 
      mutate(Name_country_common = countryname(NAME)) %>%
      left_join(countries_avgs, by = c("Name_country_common" = "resp_country_common"))  %>% 
      filter(Name_country_common != "Antarctica") %>% 
      select(Name_country_common, df_prejudice_all_cut) %>% 
      arrange(Name_country_common)
  
  # create heatmap
    p2 <-
      ggplot(data = world_map_clean) +
      geom_sf(aes(fill = df_prejudice_all_cut), color = "white", size = 0.3) +
      theme_bw() +
      theme(
        panel.grid.major = element_line(colour = "transparent"),
        axis.line = element_blank(), axis.text = element_blank(),
        panel.border=element_blank(),
        legend.title = element_blank(),
        title = element_text(face = "bold", color = "black"),
        axis.ticks = element_blank(),
        plot.margin = unit(c(0,0,0,0), "cm"),
        axis.title = element_blank()) +
        scale_fill_manual(values=c(
          "#79bf77", # green
          "#ffd97d", # yellow
          "#d53e4f" # red
          ), na.value = "grey90") + 
      scale_size(range=c(5,20)) + 
      theme(legend.position="bottom")
    
  # function to make legend small  
    addSmallLegend <- function(myPlot, position = c(0.5, -0.05), pointSize = 2, textSize = 16, spaceLegend = 0.5) {
      myPlot +
        guides(
          shape = guide_legend(override.aes = list(size = pointSize)),
          color = guide_legend(override.aes = list(size = pointSize))) +
        theme(
          legend.text  = element_text(size = textSize),
          legend.key.size = unit(spaceLegend, "lines"),
          legend.position = position,
          legend.direction = "horizontal",
          plot.margin = unit(c(-1,-1,-1,-1), "cm"))
    }
    
  # save to pdf file
    pdf("_temp_figs/descriptives_2.pdf", width = 8, height = 5)
    addSmallLegend(p2)
    dev.off()

######## plot C: overall rates by question-type #########

  # collapse down to question type
    out <- 
      analysis_df_outgroups %>% 
      group_by(qinfo_type) %>% 
        summarise(
          mean = round(mean(resp_soc_dist_bin_recode)*100, 0),
          n = n()) %>% 
      arrange(desc(mean)) %>%
      mutate(
        group = 
          case_when(
            str_detect(qinfo_type, "Distance") ~ "Acceptance of religious outgroup as...",
            TRUE ~ "... in members of religious outgroup"),
        group = 
           factor(
             group, 
             ordered = T,  
             levels = c("Acceptance of religious outgroup as...", "... in members of religious outgroup"), 
             labels = c("(i) Non-acceptance of religious outgroup as...", "(ii) Degree of ... members of religious outgroup")),
        qinfo_type = 
           factor(
             qinfo_type, 
             ordered = T,  
             levels = c("Discomfort", "Favorability", "Trust", "Distance, citizen", "Distance, neighbor", "Distance, work", "Distance, friend", "Distance, family"), 
             labels = c("Discomfort with", "Unfavorability toward", "Distrust in", "Citizen", "Neighbor", "Work associate", "Friend", "Family")))
    
  # plot
    p3 <- 
      ggplot(out, 
             aes(x = qinfo_type, y = mean, label = mean)) + 
        geom_point(stat = 'identity', fill = "gray", size = 8)  +
        geom_segment(aes(y = 0, 
                         x = qinfo_type, 
                         yend = mean, 
                         xend = qinfo_type), 
                     color = "black") +
        geom_text(color="white", size = 3) +
        labs(y = "% expressing intolerant attitude toward\nreligious outgroup", x = "") +
        theme_bw() +
        ylim(0, 50) +
        facet_wrap(~group, nrow = 2, scales = "free_y")+
        coord_flip() +
        theme(
          axis.text = element_text(size = 17),
          strip.text = element_text(size = 15),
          axis.title.x = element_text(size = 17))
    
  # save to pdf file
    pdf("_temp_figs/descriptives_3.pdf", width = 8, height = 5)
    p3
    dev.off()

######## combine plots #########
    
  # load pdf images
    im_A <- ggdraw() + draw_image(magick::image_read_pdf("_temp_figs/descriptives_1.pdf", density = 600), scale = 1)
    im_B <- ggdraw() + draw_image(magick::image_read_pdf("_temp_figs/descriptives_2.pdf", density = 600), scale = 1.1)
    im_C <- ggdraw() + draw_image(magick::image_read_pdf("_temp_figs/descriptives_3.pdf", density = 600),  scale = 1) 
  
  # create grid plot
    right <- 
      plot_grid(
        im_B + 
          theme(
            plot.margin = unit(c(0, 1, 0, 0), "lines")),
            im_C + theme(plot.margin = unit(c(0, 0, 2, 0), "lines")),
            labels = c("B", "C"),
            ncol = 1, nrow = 2, heights = c(1, 1))
  
    p4 <- 
      plot_grid(
        im_A + theme(plot.margin = unit(c(0, 0, 0, 0), "lines")), right,
        labels = c("A", ""),
        ncol = 2, nrow = 1, 
        widths = c(1, 1.1))
    
    pdf("_main-text-figs-tabs/fig-descriptives.pdf", width = 8, height = 5)
    p4
    dev.off() 
    
  }
```

```{r fig.show = "hold", out.width = "100%", align = "center", fig.cap = "\\label{fig:main_descriptives}Average unweighted survey responses to questions about intolerance toward religious outgroups across 25 multi-national survey series. Note, surveys pose different questions about religious intolerance across countries, as well as within countries over time; further, the number and timing of surveys varies cross-nationally. Panel A plots intolerance rates for the 30 countries with the largest share of intolerant responses; the \\textit{Years} column provides the range of years covered by the integrated surveys for a given country. Panel B maps average intolerance, split into terciles, by country. Panel C shows average intolerance rates by question-type in the full sample."}
  include_graphics("_main-text-figs-tabs/fig-descriptives.pdf")
```

\clearpage

<!-- main estimation function -->

```{r}
# labels
  labeling <- 
      tribble(
         ~var_name, ~var_label, ~period,
         
         "x_within_3_months_pre_election", "<3 months", "(i) Treatment: Survey completed [X] months\nbefore election",
         "x_within_6_months_pre_election", "<6 months", "(i) Treatment: Survey completed [X] months\nbefore election",
         "x_within_9_months_pre_election", "<9 months", "(i) Treatment: Survey completed [X] months\nbefore election",
         
         "x_within_3_months_post_election", "<3 months", "(ii) Treatment: Survey completed [X] months\nafter election",
         "x_within_6_months_post_election", "<6 months", "(ii) Treatment: Survey completed [X] months\nafter election",
         "x_within_9_months_post_election", "<9 months", "(ii) Treatment: Survey completed [X] months\nafter election",
         
         "x_within_3_months_pre_post_election", "<3 months", "(iii) Treatment: Survey completed [X] months\nbefore or after election",
         "x_within_6_months_pre_post_election", "<6 months", "(iii) Treatment: Survey completed [X] months\nbefore or after election",
         "x_within_9_months_pre_post_election", "<9 months", "(iii) Treatment: Survey completed [X] months\nbefore or after election")

# estimation function
  main_est_fun <-
    function(
      outcome = "resp_soc_dist_bin_recode",
      iv = NULL,
      n_days_survey_range = 182, # 6 months as default
      subgroups = NULL,
      subgroups_label = NULL,
      dataframe = "analysis_df_outgroups") {

  # subset temp df to obs with certain date range
    df <- 
      get(dataframe) %>% 
      filter(resp_interview_start_end_date_range < n_days_survey_range) %>% 
      filter(!is.na(eval(str2expression(iv))))
  
  # more complex subsets
    if(!is.null(subgroups)) {df <- df %>% filter(eval(str2expression(subgroups)))}

  # generate weights
    df <- 
      df %>%
      group_by(country_election_cycle_id) %>%
        mutate(weight = 1/n()) %>%
      ungroup()
    
  # formula
    frm <- 
      as.formula(paste0(outcome, "~", iv))

  # main model  
    out <- 
      feols(
        frm,
        fixef = c("resp_country_common", "qinfo_type", "qinfo_target"), 
        cluster = ~country_election_cycle_id, 
        weights = df$weight,
        data = df,
        lean = T)     
        
  # tidy        
    clean_mod <-
      bind_cols(tidy(out, conf.int = T)) %>% 
      bind_cols(glance(out)) %>%
      mutate(n_clusters = summary(out)$fixef_sizes[1]) %>%
      left_join(labeling, by = c("term" = "var_name")) %>%
      mutate(
        significance =
          case_when(
            p.value >= 0.05 & p.value < 0.1 ~ "*",
            p.value >= 0.01 & p.value < 0.05 ~ "**",
            p.value < 0.01 ~ "***",
            TRUE ~ ""),
        nobs = format(nobs, big.mark = ","),
        df_name = dataframe,
        subset = subgroups, 
        subgroup_label = subgroups_label,
        n_days_survey_range = n_days_survey_range)  
    
    # clean up
      rm(df)
      return(clean_mod)
          
    }
```
  
```{r out.width = "75%", fig.cap = "\\label{fig:main_mainres}Coefficient plots of estimates from nine weighted least-squares regressions. Each regression employs a differently specified treatment variable, described in the panel titles and on the vertical axis. The unit of analysis is the respondent/question-item. Models include country, question-type, and question-target fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plot."}
# declare arguments
  args <- 
    labeling %>% 
    select(iv = var_name)

# run models
  out <- 
    pmap_dfr(args, .f = main_est_fun)
  
# # sanity check
#   library(lfe)
# 
#   df <-
#     analysis_df_outgroups %>%
#     filter(resp_interview_start_end_date_range < 182) %>%
#     filter(!is.na(x_within_6_months_pre_election)) %>% # drop cases where iv is missing
#     group_by(country_election_cycle_id) %>%
#        mutate(weight = 1/n()) %>%
#     ungroup()
# 
#   summary(felm(resp_soc_dist_bin_recode ~ x_within_6_months_pre_election | resp_country_common + qinfo_type + qinfo_target | 0 | country_election_cycle_id, data = df, weights = df$weight))  

# plot      
   out %>% 
     mutate(
       across(c(estimate, conf.low, conf.high), ~.*100),
       var_label = 
         factor(
           var_label, 
           ordered = T, 
           levels = c("<9 months", "<6 months", "<3 months"), 
           labels = c("<9 months", "<6 months", "<3 months"))) %>% 
      ggplot(aes(x = var_label, y = estimate, ymin = conf.low, ymax = conf.high)) +
      geom_pointrange(aes(group = var_label)) + 
      geom_hline(yintercept = 0, linetype = 2) +  # Line at 0
      labs(x = "", y = "Estimated effect on Pr(intolerant attitude\ntoward religious outgroup), percentage points") +
      geom_errorbar(aes(ymin = conf.low, ymax = conf.high, group = var_label), width = 0, cex = 1) +
      facet_wrap(
        ~period, 
        nrow = 4, 
        scales = "free_y") +
      geom_text(aes(y = 3.75, label = paste0(nobs, " (", n_clusters, ")")), size = 3, position = position_dodge(0.6)) +
      ylim(-4, 4.2) +   
      theme_bw() +
      theme(
        legend.position="none",
        legend.title = element_blank()) +
      coord_flip() +
      scale_fill_grey() +
      scale_color_grey() +
      theme(
        axis.text = element_text(size = 14),
        strip.text = element_text(size = 14),
        axis.title.x = element_text(size = 14))  
      ggsave("_main-text-figs-tabs/fig-text-main-results.pdf")
```

\clearpage

<!-- compute heterogeneous treatment effects -->

```{r}
# calculate intolerance tercile by country
  countries_avgs <-
    analysis_df_outgroups %>%
    group_by(resp_country_common) %>%
      summarise(
        df_prejudice_all = mean(resp_soc_dist_bin_recode, na.rm = T)) %>%
    ungroup() %>%
    mutate(
        df_prejudice_all_cut =
          cut(df_prejudice_all, quantile(df_prejudice_all, 0:3/3, na.rm = T),
              labels = c(1:3))) %>% 
    arrange(desc(df_prejudice_all))

# merge in to the main dataframe  
  analysis_df_outgroups <-
    analysis_df_outgroups %>%
    left_join(countries_avgs, by = "resp_country_common")
          
# compute heterogeneous treatment effects from scratch
  if(isTRUE(hte_mods_from_scratch)) {

  # hte function
    hte_fun <-
      function(iv = NULL,
               democracies_only = FALSE,
               subgroups = NULL, 
               group_label = NULL, 
               n_days_survey_range = 182,
               subgroup_label = NULL) {
  
    # input dataframe
      df <- analysis_df_outgroups
      
    # filter to democracies only
      if(isTRUE(democracies_only)) {df <- df %>% filter(vdem_regime_democracy == 1)}
        
    # subset to obs with certain date range
      df <- 
        df %>% 
        filter(resp_interview_start_end_date_range < n_days_survey_range)
    
    # more complex subsets
      if(!is.null(subgroups)) {df <- df %>% filter(eval(str2expression(subgroups)))}
  
    # generate weights  
      df <- 
        df %>%
        filter(!is.na(get(iv))) %>% 
        group_by(country_election_cycle_id) %>%
           mutate(weight = 1/n()) %>%
        ungroup()
      
    # declare formula
      frm <- as.formula(paste0("resp_soc_dist_bin_recode ~", iv))
  
    # run model  
      model <- 
        feols(
          frm, 
          fixef = c("resp_country_common", "qinfo_type", "qinfo_target"),
          cluster = ~country_election_cycle_id,
          weights = df$weight,
          data = df,
          lean = T)   
      
    # tidy        
      clean_mods <-
        bind_cols(tidy(model, conf.int = T)) %>% 
        bind_cols(glance(model)) %>%
        mutate(n_clusters = summary(model)$fixef_sizes[1]) %>%
        mutate(
          group_label = group_label,
          subgroup_label = subgroup_label,
          subset = subgroups,
          n_days_survey_range = n_days_survey_range)
        
      }

  # declare outcomes to map over    
    args <- 
      tribble(
        ~subgroups, ~subgroup_label, ~group_label,
        "vdem_regime_democracy == 1", "Democracy", "1. Regime",
        "vdem_regime_democracy == 0", "Autocracy", "1. Regime",
        
        "nelda_12_competitive_election_LAST == 1", "Yes", "2. Last election competitive",
        "nelda_12_competitive_election_LAST == 0", "No", "2. Last election competitive",
        
        "dpi_housesys_pr == 1", "Plurality", "3. Electoral system",
        "dpi_housesys_plurality == 1", "P.R.", "3. Electoral system",

        "dpi_subnational_govt_elected == 1", "Yes", "4. Federalism",
        "dpi_subnational_govt_elected == 0", "No", "4. Federalism",
                
        "vparty_religious_party_in_nat_assembly == 1", "Yes", "5. Religious party in national assembly",
        "vparty_religious_party_in_nat_assembly == 0", "No", "5. Religious party in national assembly",

        "relac_previous_religious_conflict == 1", "Yes", "6. Religious conflict history",
        "relac_previous_religious_conflict == 0", "No", "6. Religious conflict history",

        "df_prejudice_all_cut == 1", "Least", "7. Mean intolerance tercile",
        "df_prejudice_all_cut == 2", "Medium", "7. Mean intolerance tercile",
        "df_prejudice_all_cut == 3", "Most", "7. Mean intolerance tercile",

        "relfp_relfrac_givenyear_above_median == 1", "Above median", "8. Religious fractionalization",    
        "relfp_relfrac_givenyear_above_median == 0", "Below median", "8. Religious fractionalization",    
  
        "relfp_relpol_givenyear_above_median == 1", "Above median", "9. Religious polarization",    
        "relfp_relpol_givenyear_above_median == 0", "Below median", "9. Religious polarization",  

        "nelda_last_and_next_election_oncycle == 1", "Yes", "10. On-cycle elections",
        "nelda_last_and_next_election_oncycle == 0", "No", "10. On-cycle elections",
        
        "un_gdppd_2022_prices_above_median_for_given_year == 1", "Above median", "11. GDP per capita",
        "un_gdppd_2022_prices_above_median_for_given_year == 0", "Below median", "11. GDP per capita",
  
        "resp_member_largest_religion == 1", "Yes", "12. Resp. belongs to largest religion",
        "resp_member_largest_religion == 0", "No", "12. Resp. belongs to largest religion",
        
        "resp_edu_1_noedu == 1", "None", "13. Resp. education",
        "resp_edu_2_primary_to_college == 1", "Primary", "13. Resp. education",
        "resp_edu_3_college == 1", "College", "13. Resp. education") %>% 
      expand_grid(
        iv = c(
          "x_within_3_months_pre_election",
          "x_within_6_months_pre_election",
          "x_within_9_months_pre_election",
          
          "x_within_3_months_post_election",
          "x_within_6_months_post_election",
          "x_within_9_months_post_election",

          "x_within_3_months_pre_post_election",
          "x_within_6_months_pre_post_election",
          "x_within_9_months_pre_post_election"))

  # run models (in 3 parts to avoi memory issues) 
    het_res_1 <- 
      pmap_dfr(args %>% filter(str_detect(iv, "months_pre_election")), .f = hte_fun)
    
    het_res_2 <- 
      pmap_dfr(args %>% filter(str_detect(iv, "months_post_election")), .f = hte_fun)
    
    het_res_3 <- 
      pmap_dfr(args %>% filter(str_detect(iv, "months_pre_post_election")), .f = hte_fun)
    
    het_res <- 
      het_res_1 %>% 
      bind_rows(het_res_2) %>% 
      bind_rows(het_res_3)
    
  # save
    saveRDS(het_res, "_temp_res/het_res.rds")  
    
  }

# load hte results
  het_res <-
    readRDS("_temp_res/het_res.rds")
```

<!-- generate heterogeneous treatment effects plots -->

```{r}
# hte figure
  if(isTRUE(hte_figs_from_scratch)) {

# function to make hte plots
  hte_fig_fun <- 
    function(
      iv = NULL,
      filename = NULL,
      ylims = 15) {
  
      list_levels <- 
        c("1. Regime", 
          "2. Last election competitive", 
          "3. Electoral system", 
          "4. Federalism", 
          "5. Religious party in national assembly", 
          "6. Religious conflict history", 
          "7. Mean intolerance tercile", 
          "8. Religious fractionalization", 
          "9. Religious polarization",
          "10. On-cycle elections", 
          "11. GDP per capita", 
          "12. Resp. belongs to largest religion",
          "13. Resp. education")
      
    # group data
      data <- 
        het_res %>%
        filter(term == iv) %>% 
        mutate(group_number = match(group_label, list_levels)) %>%
        group_by(group_number)  %>%
          do(add_row(., .before = 1)) %>%
        ungroup() %>% 
        mutate(
          subgroup_label = ifelse(is.na(subgroup_label), lead(group_label), subgroup_label),
          nobs = ifelse(!is.na(nobs), paste0(format(nobs, big.mark = ","), " (", n_clusters, ")"), NA)) %>% 
        select(subgroup_label, nobs, estimate, conf.low, conf.high) %>%
        rename(
          Subgroup = subgroup_label,
          'N (countries)' = nobs,
          Estimate = estimate,
          'CI low' = conf.low,
          'CI high' = conf.high) %>% 
        mutate(across(c(Estimate, `CI low`, `CI high`), ~.*100))
        
      table <- 
        data %>% 
        mutate(across(c(Estimate, `CI low`, `CI high`), ~sprintf(., fmt = '%#.2f')),
               across(c(`N (countries)`, Estimate), as.character)) %>%     
        mutate(across(everything(), ~replace_na(.x, " ")),
               Subgroup = ifelse(`N (countries)` == " ", Subgroup, paste0("     ", Subgroup)),
               `Estimate (95% CI)` = ifelse(`N (countries)` == " ", " ", paste0(Estimate, " (", `CI low`, " to ", `CI high`, ")")),
               ` ` = "                                                      ") %>% 
        select(Subgroup, `N (countries)`, ` `, `Estimate (95% CI)`) 
      
    # the main figure - this will be overlaid on the table
      center <- 
        ggplot(data = data %>% mutate(row_num = (nrow(.) - 1):0), aes(y = row_num, x = Estimate)) +
        geom_point(size = 2) + # the point estimates, with big dots
        geom_errorbarh(aes(y = row_num, 
                         xmin = `CI low`, 
                         xmax = `CI high`), 
                         height = 0) + # the CIs, with short ends
        theme_classic() + # base theme 
        scale_y_continuous(expand = c(0, 0), limits = c(-1.1, 42.1)) + # remove padding
        theme(axis.title.y = element_blank(), # remove axis, make bg transparent
              axis.text.y = element_blank(),
              axis.ticks.y = element_blank(),
              axis.line.y = element_blank(),
              axis.ticks.length.x = unit(.1, "in"),
              text = element_text(family = "sans", size = 12),
              panel.background = element_rect(fill = "transparent"), 
              plot.background = element_rect(fill = "transparent", color = NA), 
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(), 
              legend.background = element_rect(fill = "transparent"),
              legend.box.background = element_rect(fill = "transparent")) +
        geom_vline(xintercept = 0, linetype = "dashed") +
        theme(plot.margin = unit(c(0.8, 0, 0, 0), "cm")) + 
        scale_x_continuous(breaks = c(-10, 0, 10), 
                           limits = c(-ylims, ylims),
                           labels = scales::number_format(accuracy = 0.1), 
                           expand = c(0,0)) +
        xlab("Estimated effect on Pr(intolerant attitude\ntoward religious outgroup), percentage points")
      
    # format and style of the table
      hj <- matrix(c(0, 0.5,0.5, 1), ncol = 4, nrow = nrow(table), byrow = TRUE)
      x <- matrix(c(0.05, 0.5, 0.5, 0.95), ncol = 4, nrow = nrow(table), byrow = TRUE)
    
      t1 <- 
        ttheme_minimal(
          core = list(
            fg_params = list(hjust = as.vector(hj), x = as.vector(x), fontfamily = "sans"),
            bg_params = list(fill = c(rep(c("#dbd9db", "white"), length.out = 4)))),
          colhead = list(
            fg_params = list(hjust = c(0, 0.5,0.5, 1), x = c(0.05, 0.5, 0.5, 0.95), fontfamily = "sans"),
            bg_params = list(fill = "white")))
    
    # defining the layout (if data changes, layout needs to change too)
      layout <- 
        c(area(t = 1, b = 2000, l = 1, r = 80),
          area(t = 100, b = 1950, l = 41, r = 59)) # changed l = 39 to l = 40; could be l = 41, check
    
    # combine the pieces
      final <- 
        wrap_elements(tableGrob(table, theme = t1, rows = NULL)) +
        center + 
        plot_layout(design = layout)
    
    # save the table as a png
      ggsave(
        dpi = 1200, height = 14.2, 
        width = 11, units = "in", 
        filename = "fig_without_trim.png")
      
    # trim white spaces
      plt <- magick::image_read("fig_without_trim.png")
      new_plt <- magick::image_trim(plt)
      
    # save as png
      magick::image_write(new_plt, filename, quality = 275)
      
    }

# make main paper plot
  hte_fig_fun("x_within_6_months_pre_election", "_main-text-figs-tabs/fig-hte-6pre.png")
  
  }
```

<!-- print heterogeneous treatment effects plot for main paper -->

```{r fig.show = "hold", out.width = "75%", align = "center", fig.cap="\\label{fig:main_hte}Subgroup effects. Estimates from weighted least-squares regressions that include country, question-type, and question-target fixed effects. The treatment variable is an indicator for whether the respondent was surveyed within six months prior to a national election. The unit of analysis is the respondent/question-item. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle."}
  include_graphics("_main-text-figs-tabs/fig-hte-6pre.png")
```

\clearpage

<!-- estimated effects for other outcomes -->

```{r fig.show = "hold", out.width="75%", fig.cap="\\label{fig:main_extradvs}Coefficient plots of four weighted least-squares regressions that include country fixed effects. The treatment variable is an indicator for whether the respondent was surveyed within six months prior to a national election. The unit of analysis is the respondent. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plot."}
# run models
  out <-
    bind_rows(main_est_fun(dataframe = "analysis_df_gentrust", iv = "x_within_6_months_pre_election")) %>% 
    bind_rows(main_est_fun(dataframe = "analysis_df_gentrust", subgroups = "resp_has_religion == 1", iv = "x_within_6_months_pre_election")) %>%
    bind_rows(main_est_fun(dataframe = "analysis_df_religiosity", iv = "x_within_6_months_pre_election")) %>% 
    bind_rows(main_est_fun(dataframe = "analysis_df_has_and_doesnt_have_religion", iv = "x_within_6_months_pre_election", outcome = "resp_has_religion")) %>%  
    mutate(
      subset = 
        case_when(
        subset == "resp_has_religion == 1" ~ "Religious only",
        TRUE ~ "Full sample"))

# # sanity check
#   library(lfe)
# 
#   df <-
#     analysis_df_gentrust %>%
#     filter(resp_interview_start_end_date_range < 182) %>%
#     filter(!is.na(x_within_6_months_pre_election)) %>% # drop cases where iv is missing
#     group_by(country_election_cycle_id) %>%
#        mutate(weight = 1/n()) %>%
#     ungroup()
# 
#   summary(felm(resp_soc_dist_bin_recode ~ x_within_6_months_pre_election | resp_country_common | 0 | country_election_cycle_id, data = df, weights = df$weight))

# plot
  out %>% 
    mutate(
      across(c(estimate, conf.low, conf.high), ~.*100),
      subset = 
        factor(
          subset, 
          ordered = T, 
          levels = c("Religious only", "Full sample"), 
          labels = c("Religious\nresp. only", "Full sample"))) %>% 
    ggplot(aes(x = subset, y = estimate, ymin = conf.low, ymax = conf.high)) +
    geom_pointrange(aes(group = var_label), size = 0.75) + 
    geom_hline(yintercept = 0, linetype = 2) +  # Line at 0
    labs(x="", y="Estimated effect, percentage points") +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high,group = var_label), width = 0, cex = 1) + 
    facet_wrap(
      ~df_name, 
      labeller = 
        labeller(
          df_name = c(
            "analysis_df_gentrust" = "(i) Outcome: Generalized social distrust",
            "analysis_df_religiosity" = "(iiI) Outcome: Religiosity",
            "analysis_df_has_and_doesnt_have_religion" = "(ii) Outcome: Resp. reports having any religion")),
      nrow = 4, 
      scales = "free_y") +
    geom_text(aes(y = 3.4, label = paste0(nobs, " (", n_clusters, ")")), size = 4, position = position_dodge(0.6)) +
    ylim(-7.5, 4.3) +   
    theme_bw() +
    theme(
      legend.position="none",
      legend.title = element_blank(),
      axis.text = element_text(size = 14),
      strip.text = element_text(size = 16),
      axis.title.x = element_text(size = 14)) +
    coord_flip() +
    scale_fill_grey() +
    scale_color_grey()
    ggsave("_main-text-figs-tabs/fig-text-additional-outcomes.pdf")
```

#  {-}

\newpage
\appendix

\addcontentsline{toc}{section}{Appendix} 
\part{}

\setcounter{page}{0}
\pagenumbering{arabic}
\setcounter{page}{1}

\setcounter{figure}{0}
\setcounter{table}{0}
\renewcommand{\thefigure}{S\arabic{figure}}
\renewcommand{\thetable}{S\arabic{table}}

\begin{center}
\huge{SUPPORTING INFORMATION}
\end{center}

\begin{center}
\Large{\textbf{``Election Cycles and Global Religious Intolerance''}}
\end{center}

\vspace{20pt}

\begin{center}
\large{Gareth Nellis*}
\end{center}

\begin{center}
\large{\textit{*Department of Political Science, University of California, San Diego}}
\end{center}

\vspace{20pt}

\begin{center}
\large{December 2022}
\end{center}

\newpage

\parttoc

\clearpage

\section{Additional figures}

<!-- specification curve analysis -->

```{r fig.cap="\\label{fig:app_speccurve}Specification curve analysis assessing the robustness of the primary results to all combinations of modeling choices. The upper coefficient plot shows point estimates, ordered by magnitude, and 95 percent confidence intervals. Light blue coefficients are those for which the null hypothesis of no effect is rejected at the 95 percent confidence level. (In total, 14 out of 648, or 2 percent of estimates are statistically significant at the 95 percent level, and all significant effects are associated with negatively signed coefficients.) The lower plots show the analytical choices made---with each affirmative choice denoted by a black tick---in the generation of each vertically aligned coefficient in the upper plot. \\textit{Date precision} refers to the size of the time bracket within which an individual's survey date can be accurately pinpointed. \\textit{Clustering} refers to the level at which standard errors are clustered."}

# declare arguments for function
  args <- 
    as_tibble(
      expand.grid(
        date_sensitivity = c(
          91,
          182,
          274),
        weighting = c(
          "",
          "resp_country_common",
          "country_election_cycle_id"),
        clustering = c(
          "resp_country_common",
          "country_election_cycle_id"),        
        iv = c(
          "x_within_3_months_pre_election",
          "x_within_6_months_pre_election",
          "x_within_9_months_pre_election",

          "x_within_3_months_post_election",
          "x_within_6_months_post_election",
          "x_within_9_months_post_election",

          "x_within_3_months_pre_post_election",
          "x_within_6_months_pre_post_election",
          "x_within_9_months_pre_post_election"),
        fe = c(
          "",
          "resp_country_common", 
          "resp_country_common + qinfo_type", 
          "resp_country_common + qinfo_type + qinfo_target")
        )) %>% 
    mutate(across(everything(), as.character))

# estimation function
  sca_est_fun <- 
    function(
      date_sensitivity = NULL,
      weighting = NULL,
      clustering = NULL,
      iv = NULL,
      fe = NULL,
      controls = NULL) {
      
          dftemp <- 
            analysis_df_outgroups %>% 
            filter(resp_interview_start_end_date_range < date_sensitivity)
      
          if(weighting == "") {
            dftemp <- 
              dftemp %>% 
              mutate(weight = 1)
          
            } else {
            
            dftemp <- 
              dftemp %>% 
              filter(!is.na(get(iv))) %>% 
              group_by(get(weighting)) %>% 
                mutate(weight = 1/n()) %>%
              ungroup()              
            
            }
          
          if(clustering == "resp_country_common") {
            
            dftemp <- 
              dftemp %>% 
              mutate(temp_cluster = resp_country_common)
            
          }

          if(clustering == "country_election_cycle_id") {
            
            dftemp <- 
              dftemp %>% 
              mutate(temp_cluster = country_election_cycle_id)
            
          }

          frm <- 
            as.formula(paste0("resp_soc_dist_bin_recode ~", iv))
  
          out <- 
            feols(frm, 
                  fixef = unlist(strsplit(fe, " \\+ ")),
                  cluster = ~temp_cluster, 
                  weights = dftemp$weight,
                  data = dftemp) %>% 
            tidy(conf.int = T) %>% 
            filter(term == iv) %>% 
            mutate(
              cluster = clustering,
              date_range = date_sensitivity,
              weights = weighting,
              fe_set = fe)    
      
    }
  
  if(isTRUE(speccurve_from_scratch)) {
      
    # run estimation function
      res_3pre <- pmap_dfr(args %>% filter(iv == "x_within_3_months_pre_election"), .f = sca_est_fun)
      res_6pre <- pmap_dfr(args %>% filter(iv == "x_within_6_months_pre_election"), .f = sca_est_fun)
      res_9pre <- pmap_dfr(args %>% filter(iv == "x_within_9_months_pre_election"), .f = sca_est_fun)
      
      res_3post <- pmap_dfr(args %>% filter(iv == "x_within_3_months_post_election"), .f = sca_est_fun)
      res_6post <- pmap_dfr(args %>% filter(iv == "x_within_6_months_post_election"), .f = sca_est_fun)
      res_9post <- pmap_dfr(args %>% filter(iv == "x_within_9_months_post_election"), .f = sca_est_fun)
      
      res_3prepost <- pmap_dfr(args %>% filter(iv == "x_within_3_months_pre_post_election"), .f = sca_est_fun)
      res_6prepost <- pmap_dfr(args %>% filter(iv == "x_within_6_months_pre_post_election"), .f = sca_est_fun)
      res_9prepost <- pmap_dfr(args %>% filter(iv == "x_within_9_months_pre_post_election"), .f = sca_est_fun)
      
      res_compiled <- 
        bind_rows(res_3pre) %>% 
        bind_rows(res_6pre) %>% 
        bind_rows(res_9pre) %>% 
        bind_rows(res_3post) %>% 
        bind_rows(res_6post) %>% 
        bind_rows(res_9post) %>% 
        bind_rows(res_3prepost) %>% 
        bind_rows(res_6prepost) %>% 
        bind_rows(res_9prepost)
      
      saveRDS(res_compiled, "_temp_res/res_spec_curve.rds")
      
  }
  
# read in spec curve dataframe
  res <- 
    readRDS("_temp_res/res_spec_curve.rds")

# formatting  
  res_formatted <- 
    res %>% 
    arrange(estimate) %>% 
    mutate(h_order = 1:n(),
           sig_95_pct = (p.value < 0.05)*1) %>%
    mutate(
      date_range = 
        dplyr::recode(date_range,
               `274` = "(3) 274 days",
               `182` = "(2) 182 days",
               `91` = "(1) 91 days"),
      cluster = 
        dplyr::recode(cluster,
               "resp_country_common" = "(1) Country",
               "country_election_cycle_id" = "(2) Country/election cycle"),
      weights = 
        case_when(
          weights == "" ~ "(1) None",
          weights == "resp_country_common" ~ "(2) Country",
          weights == "country_election_cycle_id" ~ "(3) Country/election cycle"),
      fe_set = 
        case_when(
          fe_set == "" ~ "(1) None",
          fe_set == "resp_country_common + qinfo_type + qinfo_target" ~ "(4) Country + Question type + Question target",
          fe_set == "resp_country_common + qinfo_type" ~ "(3) Country + Question type",
          fe_set == "resp_country_common" ~ "(2) Country"),
      term = 
        dplyr::recode(term,
              "x_within_3_months_pre_election" = "(1) Surveyed <3 months pre-election",
              "x_within_6_months_pre_election" = "(2) Surveyed <6 months pre-election",
              "x_within_9_months_pre_election" = "(3) Surveyed <9 months pre-election",
    
              "x_within_3_months_post_election" = "(4) Surveyed <3 months post-election",
              "x_within_6_months_post_election" = "(5) Surveyed <6 months post-election",
              "x_within_9_months_post_election" = "(6) Surveyed <9 months post-election",
    
              "x_within_3_months_pre_post_election" = "(7) Surveyed <3 months pre/post-election",
              "x_within_6_months_pre_post_election" = "(8) Surveyed <6 months pre/post-election",
              "x_within_9_months_pre_post_election" = "(9) Surveyed <9 months pre/post-election")) %>% 
    rename(
      `Clustering` = cluster,
      `Date precision` = date_range,
      `Weights` = weights,
      `Treatment` = term,
      `Fixed effects` = fe_set) %>% 
    mutate(across(c(estimate, conf.low, conf.high), ~.*100))

# top plot
  coef_plot <- 
    ggplot(res_formatted, aes(x = h_order, y = estimate, ymin = conf.low, ymax = conf.high, color = sig_95_pct)) + 
    geom_pointrange(size = 0.1, fatten = 0.2) + 
    labs(y = "Estimated effect\non Pr(intolerant\nattitude toward\nreligious outgroup),\npercentage points", x = "") + 
    geom_hline(yintercept = 0, color = "red") +
    theme_bw() +
    theme(
      axis.title.x = element_blank(), 
      axis.ticks.x = element_blank(), 
      axis.line.x = element_blank(), 
      axis.text.x = element_blank(),
      axis.title.y = element_text(size = 8),
      legend.position="none")

# function for bottom plots  
  make_spec_plot <- 
    function(category) {
  
      specs <- 
        dummy_cols(res_formatted, select_columns = category, remove_selected_columns = T) %>%
        select(h_order, starts_with(category)) %>% 
        pivot_longer(starts_with(category), names_prefix = paste0(category, "_")) %>%
        mutate(name = factor(name, levels = rev(unique(name)))) 
      
      spec_plot <- 
        ggplot(specs, aes(x = h_order, y = name, alpha = value)) +
        geom_point(shape = 73) + 
        scale_alpha_continuous(guide = FALSE) +
        theme_gray() +
        theme(
          axis.title.x = element_blank(), 
          axis.ticks.x = element_blank(), 
          axis.line.x = element_blank(), 
          axis.text.x = element_blank(),
          axis.text.y = element_text(size = 6), 
          axis.title.y = element_blank())
      spec_plot    
  }

# declare option sets  
  spec_cols <- 
    c("Fixed effects", "Weights", "Clustering", "Date precision", "Treatment")

# loop over option sets  
  spec_plots <- 
    map(spec_cols, make_spec_plot)

# com  
  plot_grid(
    plotlist = c(list(coef_plot), spec_plots), 
    labels = c("", spec_cols), 
    label_size = 8, 
    label_fontface = "italic", 
    axis = "lr",
    vjust = 0.5, 
    hjust = -0.1,
    rel_heights = c(1, 0.4, 0.4, 0.25, 0.4, 0.6), 
    ncol = 1, 
    align = "v")
```

\clearpage

<!-- results by survey series [4 largest series that are not global-region specific] -->

```{r out.width="130%", fig.cap = "\\label{fig:app_resbyseries}Coefficient plots of estimates from weighted least-squares regressions for the four cross-regional survey series that have the largest overall samples. Regressions employ variously specified treatment variables, described on the right and left vertical axes. The unit of analysis is the respondent/question-item. Models include country, question-type, and question-target fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plots. Statistical significance is indicated on the left-hand sides of the plots: *p<0.1; **p<0.05; ***p<0.01."}

# declare arguments   
  args <- 
    tribble(
      ~subgroups, ~subgroups_label,
      'resp_source == "World Values Survey"', "(a) World Values\nSurvey",
      'resp_source == "Pew Global Attitudes Project"', "(b) Pew Global\nAttitudes Project",
      'resp_source == "International Social Survey Programme"', "(c) International\nSocial Survey\nProgramme",
      'resp_source == "Life in Transition Survey"', "(d) Life in\nTransition Survey") %>% 
    expand_grid(
      iv = c(
        "x_within_3_months_pre_election",
        "x_within_6_months_pre_election",
        "x_within_9_months_pre_election",
        
        "x_within_3_months_post_election",
        "x_within_6_months_post_election",
        "x_within_9_months_post_election",

        "x_within_3_months_pre_post_election",
        "x_within_6_months_pre_post_election",
        "x_within_9_months_pre_post_election"))  

# run models  
  res <- 
    pmap_dfr(args, .f = main_est_fun) %>% 
    mutate(
      var_label = 
        factor(
          var_label, 
          ordered = T, 
          levels = c("<9 months", "<6 months", "<3 months"), 
          labels = c("<9 months", "<6 months", "<3 months")),
      period = 
        case_when(
          str_detect(period, "\\(i\\)") ~ "(i) Treatment:\nSurveyed\n[X] months\nbefore election",
          str_detect(period, "\\(ii\\)") ~ "(ii) Treatment:\nSurveyed\n[X] months \nafter election",
          str_detect(period, "\\(iii\\)") ~ "(iii) Treatment:\nSurveyed\n[X] months\nbefore or after\nelection"),
      nobs = format(nobs, big.mark=",")) 

# plot  
  res %>% 
    mutate(across(c(estimate, conf.low, conf.high), ~.*100)) %>% 
    ggplot(
    aes(x = var_label, y = estimate, ymin = conf.low, ymax = conf.high)) +
    geom_pointrange(aes(group = var_label), size = 0.3) + 
    geom_hline(yintercept = 0, linetype = 2) +  # Line at 0
    labs(x="", y="Estimated effect on Pr(intolerant attitude\ntoward religious outgroup), percentage points") +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high,group = var_label),width = 0,cex = 0.6) +
    facet_grid(rows = vars(period), cols = vars(subgroup_label), scales = "free_y", space = "free_x") + 
    geom_text(aes(y = -12, label = significance), size = 2, position = position_dodge(0.6)) +
    geom_text(aes(y = 10, label = paste0(nobs, " (", n_clusters, ")")), size = 1.75, position = position_dodge(0.6), vjust = -0.5) +
    ylim(-13, 15) +   
    theme_bw() +
    theme(
    legend.position="none",
    legend.title = element_blank()) +
    coord_flip() +
    scale_fill_grey() +
    scale_color_grey() +
    theme(
      axis.text.x = element_text(angle = 45, vjust = 1, hjust=1, size = 6),
      axis.title.x = element_text(size = 9))
```

\clearpage

<!-- results by region -->

```{r fig.cap = "\\label{fig:app_resbyregion}Coefficient plots of estimates from weighted least-squares regressions for each global region. Regressions employ variously specified treatment variables, described on the right and left vertical axes. The unit of analysis is the respondent/question-item. Models include country, question-type, and question-target fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plots. Statistical significance is indicated on the left-hand sides of the plots: *p<0.1; **p<0.05; ***p<0.01."}
# declare arguments    
  args <- 
    tribble(
      ~subgroups, ~subgroups_label,
      'region == "Europe & North America"', "(a) Europe &\nNorth America",
      'region == "Middle East & North Africa"', "(b) Middle East\n& North Africa",
      'region == "Asia & Pacific"', "(c) Asia &\nPacific",
      'region == "Sub-Saharan Africa"', "(d) Sub-\nSaharan Africa",
      'region == "Latin America"', "(e) Latin\nAmerica") %>% 
    expand_grid(
      iv = c(
        "x_within_3_months_pre_election",
        "x_within_6_months_pre_election",
        "x_within_9_months_pre_election",
        
        "x_within_3_months_post_election",
        "x_within_6_months_post_election",
        "x_within_9_months_post_election",

        "x_within_3_months_pre_post_election",
        "x_within_6_months_pre_post_election",
        "x_within_9_months_pre_post_election")) 

rm(analysis_df)

# run models  
  res <- 
    pmap_dfr(args, .f = main_est_fun) %>% 
    mutate(
      var_label = 
        factor(
          var_label, 
          ordered = T, 
          levels = c("<9 months", "<6 months", "<3 months"), 
          labels = c("<9 months", "<6 months", "<3 months")),
      period = 
        case_when(
          str_detect(period, "\\(i\\)") ~ "(i) Treatment:\nSurveyed [X] months\nbefore election",
          str_detect(period, "\\(ii\\)") ~ "(ii) Treatment:\nSurveyed [X] months\nafter election",
          str_detect(period, "\\(iii\\)") ~ "(iii) Treatment:\nSurveyed [X] months\nbefore or after election"),
      nobs = format(nobs, big.mark=",")) 
    
# plot  
  res %>% 
    mutate(across(c(estimate, conf.low, conf.high), ~.*100)) %>%
    ggplot(
    aes(x = var_label, y = estimate, ymin = conf.low, ymax = conf.high)) +
    geom_pointrange(aes(group = var_label), size = 0.3) + 
    geom_hline(yintercept = 0, linetype=2) +
    labs(x="", y="Estimated effect on Pr(intolerant attitude\ntoward religious outgroup), percentage points") +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high,group = var_label), width = 0,cex = 0.6) +
    facet_grid(rows = vars(period), cols = vars(subgroup_label), scales = "free_y", space = "free_x") + 
    geom_text(aes(y = -9, label = significance), size = 2, position = position_dodge(0.6)) +
    geom_text(aes(y = 17, label = paste0(nobs, " (", n_clusters, ")")), size = 1.75, position = position_dodge(0.6), vjust = -0.5) +
    ylim(-10, 25) +   
    theme_bw() +
    theme(
    legend.position="none",
    legend.title = element_blank()) +
    coord_flip() +
    scale_fill_grey() +
    scale_color_grey() +
    theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1, size = 7),
    axis.title.x = element_text(size = 9),
    strip.text.x = element_text(size = 8),
    strip.text.y = element_text(size = 7))
```

\clearpage

<!-- results by religion-target -->

```{r fig.cap = "\\label{fig:app_resbyreligtar}Coefficient plots of estimates from weighted least-squares regressions for the four most numerous ``target'' religious groups (including ``Different religion'') specified in the question-text. Regressions employ variously specified treatment variables, described on the right and left vertical axes. The unit of analysis is the respondent/question-item. Models include country and question-type fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plots. Statistical significance is indicated on the left-hand sides of the plots: *p<0.1; **p<0.05; ***p<0.01."}
# declare balance outcomes to map over    
  args <- 
    tribble(
      ~subgroups, ~subgroups_label,
      'qinfo_target == "Different religion"', "(a) Different religion",
      'qinfo_target == "Christian"', "(b) Christian",
      'qinfo_target == "Muslim"', "(c) Muslim",
      'qinfo_target == "Jewish"', "(d) Jewish") %>% 
    expand_grid(
      iv = c(
        "x_within_3_months_pre_election",
        "x_within_6_months_pre_election",
        "x_within_9_months_pre_election",
        
        "x_within_3_months_post_election",
        "x_within_6_months_post_election",
        "x_within_9_months_post_election",

        "x_within_3_months_pre_post_election",
        "x_within_6_months_pre_post_election",
        "x_within_9_months_pre_post_election")) 

# run models  
  res <- 
    pmap_dfr(args, .f = main_est_fun) %>% 
    mutate(
      var_label = 
        factor(
          var_label, 
          ordered = T, 
          levels = c("<9 months", "<6 months", "<3 months"), 
          labels = c("<9 months", "<6 months", "<3 months")),
      period = 
        case_when(
          str_detect(period, "\\(i\\)") ~ "(i) Treatment:\nSurveyed [X] months\nbefore election",
          str_detect(period, "\\(ii\\)") ~ "(ii) Treatment:\nSurveyed [X] months\nafter election",
          str_detect(period, "\\(iii\\)") ~ "(iii) Treatment:\nSurveyed [X] months\nbefore or after election"),
      nobs = format(nobs, big.mark=",")) 
    
# plot  
  res %>% 
    mutate(across(c(estimate, conf.low, conf.high), ~.*100)) %>%
    ggplot(
    aes(x = var_label, y = estimate, ymin = conf.low, ymax = conf.high)) +
    geom_pointrange(aes(group = var_label), size = 0.3) + 
    geom_hline(yintercept = 0, linetype=2) +
    labs(x="", y="Estimated effect on Pr(intolerant attitude\ntoward religious outgroup), percentage points") +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high,group = var_label), width = 0,cex = 0.6) +
    facet_grid(rows = vars(period), cols = vars(subgroup_label), scales = "free_y", space = "free_x") + 
    geom_text(aes(y = -9, label = significance), size = 2, position = position_dodge(0.6)) +
    geom_text(aes(y = 17, label = paste0(nobs, " (", n_clusters, ")")), size = 1.75, position = position_dodge(0.6), vjust = -0.5) +
    ylim(-10, 25) +   
    theme_bw() +
    theme(
    legend.position="none",
    legend.title = element_blank()) +
    coord_flip() +
    scale_fill_grey() +
    scale_color_grey() +
    theme(
      axis.text.x = element_text(angle = 45, vjust = 1, hjust=1, size = 7),
      axis.title.x = element_text(size = 9),
      strip.text.x = element_text(size = 8),
      strip.text.y = element_text(size = 7))
```

\clearpage

<!-- correlation plot of country/election characteristics -->

```{r fig.cap = "\\label{fig:app_corrplot}Correlation plot visualizing the bivariate correlation coefficients between all pairs of nine country- or country/election-level variables used in the analysis of subgroup effects. The unit of analysis is the country/election year. There are 525 observations. For comparability, only country/election years that contain non-missing data for all nine variables are analyzed. \\textit{Democracy}, \\textit{Election system plurality}, \\textit{Election system P.R.}, \\textit{Religious conflict history}, \\textit{Last election competitive}, and \\textit{Religious party in national assembly} are the same dichotomous indicators employed in Fig. 3. \\textit{GDP per capita}, \\textit{Religious fractionalization}, \\textit{Religious polarization} are contininuous measures: the underlying variables from which dichotomous subgroups are generated in Fig. 3. \\textit{Federalism} is not included due to high levels of missingness in the original measure."}
# country/election dataframe
  out <- 
    analysis_df_outgroups %>% 
    distinct(last_election, resp_country_common, .keep_all = T) %>% 
    select(
      `Democracy` = vdem_regime_democracy,
      `Election system plurality` = dpi_housesys_plurality,
      `Election system P.R.` = dpi_housesys_pr,
      `Religious party in national assembly` = vparty_religious_party_in_nat_assembly, 
      `GDP per capita` = un_gdppd_2022_prices, 
      `Last election competitive` = nelda_12_competitive_election_LAST, 
      `Religious fractionalization` = relfp_relfrac,
      `Religious polarization` = relfp_relpol,
      `Religious conflict history` = relac_previous_religious_conflict) %>% 
    na.omit()

# run correlations
  corr <- 
    round(cor(out), 2)

# plot
  ggcorrplot(
    corr, 
    hc.order = TRUE, 
    type = "lower", 
    lab = TRUE, 
    legend.title = "Pearson\ncorrelation\ncoefficient\n",
    lab_size = 2.5, 
    method = "circle", 
    colors = c("tomato2", "white", "springgreen3"), 
    ggtheme = theme_bw)
```

\clearpage

<!-- attrition analysis -->

```{r out.width = "75%", fig.cap = "\\label{fig:app_naanalysis}Coefficient plots of estimates from nine weighted least-squares regressions analyzing the effect of election proximity on the probability of respondents offering a non-response to a question about religious intolerance. Each regression employs a differently specified treatment variable, described in the panel titles and on the vertical axis. The unit of analysis is the respondent/question-item. Models include country, question-type, and question-target fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plot."}
# decalre arguments  
  args <- 
    labeling %>% 
    select(iv = var_name) %>% 
    mutate(
      outcome = "resp_response_na", 
      dataframe = "analysis_df_outgroups_attrition")

# run models
  out <- 
    pmap_dfr(args, .f = main_est_fun)
  
# code for sanity check
  # library(lfe)
  # 
  # df2 <-
  #   analysis_df_outgroups %>%
  #   filter(resp_interview_start_end_date_range < 182) %>%
  #   filter(!is.na(x_within_9_months_pre_election) ) %>% # drop cases where iv is missing
  #   group_by(country_election_cycle_id) %>%
  #      mutate(weight = 1/n()) %>%
  #   ungroup()
  # 
  # summary(felm(resp_response_na ~ x_within_9_months_pre_election | resp_country_common + qinfo_type + qinfo_target | 0 | country_election_cycle_id, data = df2, weights = df2$weight))  

# plot      
   out %>% 
     mutate(across(c(estimate, conf.low, conf.high), ~.*100),
            var_label = factor(var_label, ordered = T, 
                               levels = c("<9 months", "<6 months", "<3 months"), 
                               labels = c("<9 months", "<6 months", "<3 months"))) %>% 
      ggplot(
         aes(x = var_label, y = estimate, ymin = conf.low, ymax = conf.high)) +
      geom_pointrange(aes(group = var_label)) + 
      geom_hline(yintercept = 0, linetype = 2) +  # Line at 0
      labs(x = "", y = "Estimated effect on Pr(Non-response to religious\nintolerance question), percentage points") +
      geom_errorbar(aes(ymin = conf.low, ymax = conf.high, group = var_label), width = 0, cex = 1) +
      facet_wrap(~period, 
                 nrow = 4, 
                 scales = "free_y") +
      geom_text(aes(y = 3.5, label = paste0(nobs, " (", n_clusters, ")")), size = 3, position = position_dodge(0.6)) +
      ylim(-4, 4) +   
      theme_bw() +
      theme(
        legend.position="none",
        legend.title = element_blank()) +
      coord_flip() +
      scale_fill_grey() +
      scale_color_grey() +
      theme(
        axis.text = element_text(size = 14),
        strip.text = element_text(size = 14),
        axis.title.x = element_text(size = 14)) 
```

\clearpage

<!-- full set of treatment effect estimates for generalized social distrust -->

```{r out.width="75%", fig.cap="\\label{fig:app_gtcomplete}Complete results for generalized social distrust, for the full sample of respondents. Coefficient plots of estimates from nine weighted least-squares regressions. Each regression employs a differently specified treatment variable, described in the panel titles and on the vertical axis. The unit of analysis is the respondent. Models include country fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plot."}

# full set of treatment effects for general social trust
# declare arguments
  args <- 
    labeling %>% 
    select(iv = var_name) %>% 
    mutate(dataframe = "analysis_df_gentrust")

# run models
  out <- 
    pmap_dfr(args, .f = main_est_fun)
  
# # sanity check
#   library(lfe)
# 
#   df <-
#     analysis_df_gentrust %>%
#     filter(resp_interview_start_end_date_range < 182) %>%
#     filter(!is.na(x_within_3_months_pre_election)) %>% # drop cases where iv is missing
#     group_by(country_election_cycle_id) %>%
#        mutate(weight = 1/n()) %>%
#     ungroup()
# 
#   summary(felm(resp_soc_dist_bin_recode ~ x_within_3_months_pre_election | resp_country_common | 0 | country_election_cycle_id, data = df, weights = df$weight))
  
# plot      
   out %>% 
     mutate(across(c(estimate, conf.low, conf.high), ~.*100)) %>% 
     mutate(var_label = 
              factor(
                var_label, 
                ordered = T, 
                levels = c("<9 months", "<6 months", "<3 months"), 
                labels = c("<9 months", "<6 months", "<3 months"))) %>% 
      ggplot(aes(x = var_label, y = estimate, ymin = conf.low, ymax = conf.high)) +
      geom_pointrange(aes(group = var_label)) + 
      geom_hline(yintercept = 0, linetype = 2) +  # Line at 0
      geom_text(aes(y = 7.5, label = paste0(nobs, " (", n_clusters, ")")), size = 3, position = position_dodge(0.6)) +
      labs(x="", y="Estimated effect on Pr(generalized social distrust),\npercentage points") +
      geom_errorbar(aes(ymin=conf.low, ymax=conf.high,group=var_label),width=0,cex=1) +
      facet_wrap(~period, 
                 nrow = 4, 
                 scales = "free_y") +
      ylim(-10, 10) +   
      theme_bw() +
      theme(
        axis.text = element_text(size = 14),
        strip.text = element_text(size = 14),
        axis.title.x = element_text(size = 14),
        legend.position="none",
        legend.title = element_blank()) +
      coord_flip() +
      scale_fill_grey() +
      scale_color_grey()
```

<!-- heterogeneous treatment effects for social distrust -->

```{r}
  if(isTRUE(hte_mods_from_scratch)) {

  # hte function
    hte_trust_fun <-
      function(
        iv = NULL,
        democracies_only = FALSE,
        subgroups = NULL, 
        group_label = NULL, 
        n_days_survey_range = 182,
        subgroup_label = NULL) {
  
    # input dataframe
      df <- analysis_df_gentrust
      
    # filter to democracies only
      if(isTRUE(democracies_only)) {df <- df %>% filter(vdem_regime_democracy == 1)}
        
    # subset to obs with certain date range
      df <- 
        df %>% 
        filter(resp_interview_start_end_date_range < n_days_survey_range)
    
    # more complex subsets
      if(!is.null(subgroups)) {df <- df %>% filter(eval(str2expression(subgroups)))}
  
    # generate weights  
      df <- 
        df %>%
        filter(!is.na(get(iv))) %>% 
        group_by(country_election_cycle_id) %>%
           mutate(weight = 1/n()) %>%
        ungroup()
      
    # declare formula
      frm <- as.formula(paste0("resp_soc_dist_bin_recode ~", iv))
  
    # run model  
      model <- 
        feols(
          frm, 
          fixef = c("resp_country_common"),
          cluster = ~country_election_cycle_id,
          weights = df$weight,
          data = df,
          lean = T)   
      
    # tidy        
      clean_mods <-
        bind_cols(tidy(model, conf.int = T)) %>% 
        bind_cols(glance(model)) %>%
        mutate(n_clusters = summary(model)$fixef_sizes[1]) %>%
        mutate(
          group_label = group_label,
          subgroup_label = subgroup_label,
          subset = subgroups,
          n_days_survey_range = n_days_survey_range)
        
      }

  # declare outcomes to map over    
    args <- 
      tribble(
        ~subgroups, ~subgroup_label, ~group_label,

        "adekw_ef_above_median == 1", "Above median", "1. Ethnic fractionalization",    
        "adekw_ef_above_median == 0", "Below median", "1. Ethnic fractionalization",    

        "adekw_lf_above_median == 1", "Above median", "2. Linguistic fractionalization",    
        "adekw_lf_above_median == 0", "Below median", "2. Linguistic fractionalization",    
        
        "relfp_relfrac_givenyear_above_median == 1", "Above median", "3. Religious fractionalization",    
        "relfp_relfrac_givenyear_above_median == 0", "Below median", "3. Religious fractionalization") %>% 
      expand_grid(
        iv = c(
          "x_within_3_months_pre_election",
          "x_within_6_months_pre_election",
          "x_within_9_months_pre_election",
          
          "x_within_3_months_post_election",
          "x_within_6_months_post_election",
          "x_within_9_months_post_election",

          "x_within_3_months_pre_post_election",
          "x_within_6_months_pre_post_election",
          "x_within_9_months_pre_post_election"))
    
  # run models (in 3 parts to avoi memory issues) 
    het_trust_res <- 
      pmap_dfr(args, .f = hte_trust_fun)

  # save
    saveRDS(het_trust_res, "_temp_res/het_trust_res.rds")  
  
  }

# load hte results
  het_trust_res <-
    readRDS("_temp_res/het_trust_res.rds")
  
# with labeling
  formatted <- 
    het_trust_res %>% 
    mutate(
      term = 
        dplyr::recode(term,
          "x_within_3_months_pre_election" = "(a) Surveyed <3 months pre-election",
          "x_within_6_months_pre_election" = "(b) Surveyed <6 months pre-election",
          "x_within_9_months_pre_election" = "(c) Surveyed <9 months pre-election",
  
          "x_within_3_months_post_election" = "(d) Surveyed <3 months post-election",
          "x_within_6_months_post_election" = "(e) Surveyed <6 months post-election",
          "x_within_9_months_post_election" = "(f) Surveyed <9 months post-election",
  
          "x_within_3_months_pre_post_election" = "(g) Surveyed <3 months pre/post-election",
          "x_within_6_months_pre_post_election" = "(h) Surveyed <6 months pre/post-election",
          "x_within_9_months_pre_post_election" = "(i) Surveyed <9 months pre/post-election"),
      facet_label = 
        paste0(group_label, ":\n", subgroup_label))
```

\begin{landscape}

```{r out.width="85%", fig.cap="\\label{fig:app_trusthte}Subgroup effects for the generalized social distrust outcome. Coefficient plots of estimates from weighted least-squares regressions. Each regression employs a differently specified treatment variable, described on the vertical axis. The unit of analysis is the respondent. Models include country fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle. The number of observations, with the number of countries in parentheses, is displayed on the right-hand side of the plots."}
  formatted %>% 
    mutate(across(c(estimate, conf.low, conf.high), ~.*100),
           term = factor(term, levels = rev(unique(term)))) %>%
    ggplot(
    aes(x = term, y = estimate, ymin = conf.low, ymax = conf.high)) +
    geom_pointrange(aes(group = term), size = 0.3) + 
    geom_hline(yintercept = 0, linetype=2) +
    labs(x="", y="Estimated effect on Pr(generalized social distrust), percentage points") +
    geom_text(aes(y = 10.5, label = paste0(format(nobs, big.mark=","), " (", n_clusters, ")")), size = 1.5, position = position_dodge(0.6)) +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high, group = term), width = 0, cex = 0.6) +
    facet_wrap(~facet_label, nrow = 3) +
    ylim(-17, 12) + 
    theme_bw() +
    theme(
    legend.position="none",
    legend.title = element_blank()) +
    coord_flip() +
    scale_fill_grey() +
    scale_color_grey() +
    theme(
      axis.text.x = element_text(size = 7),
      axis.text.y = element_text(size = 6),
      axis.title.x = element_text(size = 9),
      strip.text.x = element_text(size = 8),
      strip.text.y = element_text(size = 7))
```

\end{landscape}

<!-- binned scatter plots for continuous treatment variable -->

\clearpage

```{r}
# non-parametric loess plots 
if(isTRUE(loess_from_scratch)) {
  
  # create 2-column dataframe without nas
    analysis_df_outgroups_nas_dropped <- 
      analysis_df_outgroups %>%
      select(x_percent_through_election, resp_soc_dist_bin_recode, resp_country_common, qinfo_type, qinfo_target) %>% 
      na.omit()
    
  # quantiles, no partialling out
    binscatter_q_no_fe <-
      analysis_df_outgroups_nas_dropped %>% 
      mutate(qs = cut(x_percent_through_election, breaks = quantile(x_percent_through_election, probs = (0:40)/40))) %>% 
      group_by(qs) %>% 
        summarise(
          q_m = median(x_percent_through_election),
          q_y = mean(resp_soc_dist_bin_recode),
          q_n = n()) %>% 
      ungroup() %>% 
      filter(!is.na(qs)) %>% 
      mutate(qs = as.numeric(qs))
    
  # quantiles, with partialling out  
    binscatter_q_with_fe <-
      demeanlist(
        analysis_df_outgroups_nas_dropped %>%
          select(x_percent_through_election, resp_soc_dist_bin_recode),
        analysis_df_outgroups_nas_dropped %>% 
          select(resp_country_common, qinfo_type, qinfo_target) %>% 
          mutate_all(as.factor),
        na.rm = T) %>%
      mutate(
        qs = cut(x_percent_through_election, breaks = quantile(x_percent_through_election, probs = (0:40)/40))) %>% 
      group_by(qs) %>% 
        summarise(
          q_m = median(x_percent_through_election),
          q_y = mean(resp_soc_dist_bin_recode),
          q_n = n()) %>% 
      ungroup() %>% 
      filter(!is.na(qs)) %>% 
      mutate(qs = as.numeric(qs))
  
  # plots
    p1 <-   
      ggplot(data = binscatter_q_no_fe, aes(x = q_m, y = q_y)) +
      geom_point() +
      geom_smooth(se = F) +
      theme_bw() +
      labs(y = "Mean intolerance", x = "Percentile of treatment") +
      theme(axis.title = element_text(size = 14),
            axis.text = element_text(size = 10))
  
    p2 <-   
      ggplot(data = binscatter_q_with_fe, aes(x = q_m, y = q_y)) +
      geom_point() +
      geom_smooth(se = F) +
      theme_bw() +
      labs(y = "Residualized mean\nintolerance", x = "Residualized percentile \n of treatment")+
      theme(axis.title = element_text(size = 14),
            axis.text = element_text(size = 10))
  
  # print plots  
    p_comb <- 
      plot_grid(
        p1, p2,  
        labels = c("A", "B"),
        label_size = 20,
        ncol = 2)
    
  # save  
    ggsave("_temp_figs/fig-text-loess.pdf", width = 7, height = 3.5)
    
  }
```

```{r fig.show = "hold", out.width = "85%", align = "center", fig.cap="\\label{fig:app_binscatter}This figure presents binned scatter plots of the relationship between the stage at which individuals were surveyed in the course of the election cycle (in percentage terms) and whether they offered a negative attitude toward religious outgroups. In Panel A, I rank observations by their values on the treatment variable, and then split the data into 40 equally sized bins, according to this variable; next, I plot the bin-medians of the treatment variable against the bin-means of the outcome variable. Panel B follows the same proceduce, except both variables are first residualized to partial out country, question-type, and question-target fixed effects. Blue lines represent loess smoothers throught the binned data."}
  include_graphics("_temp_figs/fig-text-loess.pdf")
```

\clearpage

<!-- country-specific difference in means -->

```{r fig.show = "hold", out.width="70%", fig.cap = "\\label{fig:app_countryexf}Histogram showing the distribution of the differences in mean intolerance rates between election periods and non-election periods, computed separately for each country."}
# run models
  model <- 
    feols(
      resp_soc_dist_bin_recode ~ x_within_9_months_pre_post_election,
      data = analysis_df_outgroups,
      split = ~resp_country_common) %>% 
    map_dfr(., tidy, conf.int = T, .id ="resp_country_common") %>% 
    filter(term == "x_within_9_months_pre_post_election") %>% 
    mutate(estimate = estimate*100)
   
# plot
  ggplot(model, aes(estimate)) + 
    geom_histogram(color = "white", fill = "black") +
    theme_bw() +
    ylab("Number of countries") +
    xlab("% respondents offering intolerant response during election window \n (9 months before/after election) minus\n% respondents offering intolerant response outside election window")  
```

\clearpage

<!-- hte complete results plotted -->

```{r}
# hte figure
  if(isTRUE(hte_figs_from_scratch)) {

# declare levels
  list_levels = c((unique(paste0(het_res$group_label, ": ", het_res$subgroup_label))))
  
# make plot
  hte_full <- 
    het_res %>%
    mutate(across(c(estimate, conf.low, conf.high), ~.*100)) %>% 
    mutate(new_lab = paste0(group_label, ": ", subgroup_label)) %>% 
    mutate(new_lab_order = factor(new_lab, levels = list_levels)) %>% 
    ggplot(aes(x = term, y = estimate, ymin = conf.low, ymax = conf.high)) +
    geom_pointrange(aes(col = term)) +
    labs(x = "", y = "Estimated effect on Pr(intolerant attitude toward religious outgroup), percentage points") +
    ylim(-13, 20) +
    geom_text(aes(y = 15, label = paste0(nobs, " (", n_clusters, ")")), size=2.8, vjust = 0.5) +
    geom_hline(yintercept = 0, color = "black") +
    geom_errorbar(aes(ymin = conf.low, ymax = conf.high, col = term), width = 0, cex = 1) + 
    facet_wrap(.~new_lab_order, strip.position = "left", ncol = 2) +
    theme_bw() +
    theme(
      plot.title = element_text(size=16),
      plot.margin = margin(0, 0, 2, 0, "cm"), 
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank(),
      axis.text.x = element_text(size=14),
      axis.title = element_text(size=16, hjust = 0.15),
      strip.text.y.left = element_text(angle = 0, size = 18),
      strip.text.x = element_blank(),
      legend.position = "none") +
    coord_flip()
    ggsave("_temp_figs/fig-app-hetfull.pdf", hte_full, width = 17, height = 20)
    
  }
```


```{r  fig.show = "hold", fig.align="center", echo = FALSE, out.width="85%",  fig.cap="\\label{fig:app_otherhet}Complete subgroup effects. Estimates from weighted least-squares regressions that include country, question-type, and question-target fixed effects. Each subplot employs nine differently specified treatment variables (ordered as in Fig. 2). The unit of analysis is the respondent/question-item. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. 95 percent confidence intervals are based on robust standard errors clustered by country/election cycle."}
  include_graphics("_temp_figs/fig-app-hetfull.pdf")
```

\clearpage

```{r}
  if(isTRUE(figures_from_scratch)) {

# interflex function
  interflex_fun <- 
    function(
      moderator = NULL,
      indvar = NULL,
      subt = NULL) {
      
  # filter the dataframe and make weights      
    df <-
      analysis_df_outgroups %>%
      filter(resp_interview_start_end_date_range < 182) %>%
      filter(!is.na(get(indvar)) & !is.na(get(moderator))) %>%
      group_by(country_election_cycle_id) %>%
         mutate(weight = 1/n()) %>%
      ungroup() %>% 
      as.data.frame()
    
  # output interflex figure
    p <- 
      interflex(
        data = df,
        estimator = "binning",
        Y = "resp_soc_dist_bin_recode", 
        D = indvar, 
        X = moderator,
        na.rm = T,
        FE = c('qinfo_target', 'qinfo_type', 'resp_country_common'),
        cl = "country_election_cycle_id",
        weights = "weight",
        nbins = 3, 
        theme.bw = TRUE,
        Dlabel = "",
        Ylabel = "",
        Xunif = T,
        bin.labs = F,
        ylim = c(-0.05, 0.04),
        xlab = "",
        ylab = "",
        vcov.type = "robust", 
        subtitles = subt) %>% 
        .$figure
    
    # clean
      rm(df)
      return(p)

    }
  
# create plots  
  p1 <- 
    interflex_fun(
      moderator = "dalp_a8_3_party_links_to_rel_orgs_weighted", 
      indvar = "x_within_6_months_pre_election", 
      subt = "(a) Do the following parties \n have strong linkages to \n religious organizations?  \n \n")
  
  p2 <- 
    interflex_fun(
      moderator = "dalp_b10_3_relies_on_rel_orgs_to_target_benefits_weighted", 
      indvar = "x_within_6_months_pre_election", 
      subt = "(b) Do the parties most commonly \n rely on religious organizations \n in their efforts to select the \n recipients and deliver the \n benefits to the target constituencies?")
  
  p3 <- 
    interflex_fun(
      moderator = "dalp_c2_3_relies_on_rel_orgs_for_vote_info_weighted", 
      indvar = "x_within_6_months_pre_election", 
      subt = "(c) Do the parties rely on \n religious organizations to provide \n information about an individual's \n or a group's voting behavior?  \n")

  p <-
    grid.arrange(
    grobs = list(p1, p2, p3),
    ncol = 3,
    left = "Estimated marginal effect of\nSurveyed <6 months pre-election on\nPr(intolerant attitude toward\nreligious outgroup)",
    bottom = "Vote share going to parties for which the answer\nto the question in the panel-title is yes, percentile rank") 
  
# save  
  ggsave("_temp_figs/interflex.pdf", p, width = 12, height = 4)
  
  }
```

\begin{landscape}

```{r fig.show = "hold", out.width = "100%", align = "center", fig.cap = "\\label{fig:app_interflex}Estimated marginal effects according to the estimated national vote share received by parties with religious ties, as described in the Democratic Accountability and Linkages Project 2008. The unit of analysis is the respondent/question-item. Models include country, question-type, and question-target fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation."}
  include_graphics("_temp_figs/interflex.pdf")
```

\end{landscape}

```{r fig.show = "hold", out.width = "85%", align = "center", fig.cap = "\\label{fig:app_dalphist}Histograms showing the distribution of vote shares received by parties with religious ties, as described in the Democratic Accountability and Linkages Project 2008."}
# extract
  dalp_out <- 
    bind_rows(
      analysis_df_outgroups %>% 
      distinct(resp_country_common, outcome = dalp_a8_3_party_links_to_rel_orgs_weighted) %>% 
      mutate(name = "(a) Do the following parties have strong linkages to religious organizations?")) %>% 
    bind_rows(
      analysis_df_outgroups %>% 
      distinct(resp_country_common, outcome = dalp_b10_3_relies_on_rel_orgs_to_target_benefits_weighted) %>% 
      mutate(name = "(b) Do the parties most commonly rely on religious organizations in their efforts to select the recipients and deliver the benefits to the target constituencies?")) %>% 
    bind_rows(
      analysis_df_outgroups %>% 
      distinct(resp_country_common, outcome = dalp_c2_3_relies_on_rel_orgs_for_vote_info_weighted) %>% 
      mutate(name = "(c) Do the parties rely on religious organizations to provide information about an individual's or a group's voting behavior?")) %>% 
    na.omit()

# plot
  ggplot(dalp_out, aes(outcome)) + 
    geom_histogram(color = "white", fill = "black") +
    facet_wrap(~name, labeller = labeller(name = label_wrap_gen(30))) +
    theme_bw() +
    ylab("Number of countries") +
    xlab("Vote share going to parties for which the answer\nto the question in the panel-title is yes")
```

\clearpage

\section{Additional tables}

<!-- summary statistics -->

```{r}
# object for country-level variables
  analysis_df_outgroups_country <- 
    analysis_df_outgroups %>%
    distinct(resp_country_common, .keep_all = T)

# object for country/election-level variables
  analysis_df_outgroups_country_election <- 
    analysis_df_outgroups %>% 
    distinct(country_election_cycle_id, .keep_all = T)

# calculate summary stats
  sumstat_fun <- 
    function(
      var = NULL,
      lab = NULL,
      grp = NULL,
      df = NULL){
      
      v <- get(df) %>% pull(get(var))
      qs <- quantile(v, c(0.5, 0, 1), na.rm = T)
      data.frame(
        vlab = lab,
        group = grp,
        n = sum(!is.na(v)),
        mean = mean(v, na.rm = T),
        sd = sd(v, na.rm = T),
        minimum = qs[2],
        median = qs[1],
        maximum = qs[3]) %>% 
      mutate(
        mean = format(round(mean, 2), nsmall = 2),
        sd = format(round(sd, 2), nsmall = 2),
        minimum = format(round(minimum, 2), nsmall = 2),
        median = format(round(median, 2), nsmall = 2),
        maximum = format(round(maximum, 2), nsmall = 2))
    }

# list the arguments
  args <- 
    tribble(
      ~grp, ~var, ~lab, ~df,
      
    # outcomes
      "Outcome (question-item level)", "resp_soc_dist_bin_recode", "Intolerant attitude toward religious outgroup", "analysis_df_outgroups",
      "Outcome (question-item level)", "resp_soc_dist_bin_recode", "Generalized social distrust", "analysis_df_gentrust",
      "Outcome (question-item level)", "resp_soc_dist_bin_recode", "Religiosity", "analysis_df_religiosity",
      "Outcome (question-item level)", "resp_has_religion", "Resp. has religion", "analysis_df_has_and_doesnt_have_religion",
      "Outcome (question-item level)", "resp_response_na", "Non-response to religious intolerance question", "analysis_df_outgroups_attrition",

    
    # treatment variables   
      "Treatment variables (individual level)", "x_within_3_months_pre_election", "Surveyed <3 months before election", "analysis_df_outgroups_unique_rs",
      "Treatment variables (individual level)", "x_within_6_months_pre_election", "Surveyed <6 months before election", "analysis_df_outgroups_unique_rs",
      "Treatment variables (individual level)", "x_within_9_months_pre_election", "Surveyed <9 months before election", "analysis_df_outgroups_unique_rs",

      "Treatment variables (individual level)", "x_within_3_months_post_election", "Surveyed <3 months after election", "analysis_df_outgroups_unique_rs",
      "Treatment variables (individual level)", "x_within_6_months_post_election", "Surveyed <6 months after election", "analysis_df_outgroups_unique_rs",
      "Treatment variables (individual level)", "x_within_9_months_post_election", "Surveyed <9 months after election", "analysis_df_outgroups_unique_rs",

      "Treatment variables (individual level)", "x_within_3_months_pre_post_election", "Surveyed <3 months before/after election", "analysis_df_outgroups_unique_rs",
      "Treatment variables (individual level)", "x_within_6_months_pre_post_election", "Surveyed <6 months before/after election", "analysis_df_outgroups_unique_rs",
      "Treatment variables (individual level)", "x_within_9_months_pre_post_election", "Surveyed <9 months before/after election", "analysis_df_outgroups_unique_rs",
    
      "Treatment variables (individual level)", "x_percent_through_election", "Percentage through election cycle surveyed", "analysis_df_outgroups_unique_rs",
   
    # country-level characteristics
      "Country-level characteristics", "relfp_relfrac_givenyear_above_median", "Religious fractionalization above median", "analysis_df_outgroups_country",
      "Country-level characteristics", "relfp_relpol_givenyear_above_median", "Religious polarization above median", "analysis_df_outgroups_country",
      "Country-level characteristics", "adekw_lf_above_median", "Linguistic fractionalization above median", "analysis_df_outgroups_country",    
      "Country-level characteristics", "adekw_ef_above_median", "Ethnic fractionalization above median", "analysis_df_outgroups_country",    
    
    # country/election-level characteristics
      "Country/election-level characteristics", "vdem_regime_democracy", "Democracy", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "nelda_12_competitive_election_LAST", "Last election competitive", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "dpi_housesys_plurality", "Electoral system plurality", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "dpi_housesys_pr", "Electoral system P.R.", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "dpi_subnational_govt_elected", "Federalism", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "vparty_religious_party_in_nat_assembly", "Religious party in national assembly", "analysis_df_outgroups_country_election", 
      "Country/election-level characteristics", "relac_previous_religious_conflict", "Religious conflict history", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "nelda_last_and_next_election_oncycle", "On-cycle elections", "analysis_df_outgroups_country_election",
      "Country/election-level characteristics", "un_gdppd_2022_prices_above_median_for_given_year", "GDP per capita above median", "analysis_df_outgroups_country_election",

    # individual covariates  
      "Individual-level characteristics", "resp_female", "Female", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_rural", "Rural", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_age_recode", "Age", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_member_largest_religion", "Member of largest religion", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_edu_1_noedu", "Education: None", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_edu_2_primary_to_college", "Education: Primary to college", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_edu_3_college", "Education: College", "analysis_df_outgroups_unique_rs",
      "Individual-level characteristics", "resp_surveyed_in_person", "Surveyed in person", "analysis_df_outgroups_unique_rs")

# generate the dataframe  
  out <- 
    pmap_dfr(list(args$var, args$lab, args$grp, args$df), sumstat_fun) %>% 
    mutate(hist = "") %>% 
    remove_rownames() %>% 
    mutate(n = format(n, big.mark=","))

# function to grab data for histograms  
  hist_fun <- 
    function(
      df = NULL,
      var = NULL,
      newname = NULL) {
      
      v <- get(df) %>% select(newname = var) %>% pull(newname)
      
    }

# create list of data for histograms  
  hists <- 
    pmap(list(args$df, args$var, args$lab), hist_fun)

# decalre caption
  cap <- 
    "\\label{tab:app_sumstats}Summary statistics. Detailed variable descriptions are provided in SI Appendix, Table \\ref{tab:app_vardesc}. Variables are summarized at the level at which measurements were initially recorded."
  
# print table
  out %>%
    select(-group) %>% 
    kable(
      "latex",
      booktabs = T,
      escape = F,
      longtable = T,
      col.names = linebreak(c(
        "Measure",
        "N",
        "Mean",
        "St. Dev.",
        "Min.",
        "Median",
        "Max.",
        "Histogram")),
      align = c("l", rep("c", 8)),
        caption = cap,
        linesep = "") %>%
    kable_styling(
      font_size = 7,
      latex_options = c(
        "scale_down",
        "hold_position",
        "striped")) %>% 
    column_spec(8, image = spec_hist(hists, same_lim = FALSE, col = "lightblue")) %>% 
    pack_rows(index = table(fct_inorder(out$group)))
```

\clearpage

<!-- variables description and sources -->

```{r} 
# sources: original links
  out <- 
    tribble(
      ~group, ~variable, ~source, ~description,
      
       "Individual/question-item outcomes",
       "$\\bullet$ Intolerant attitude toward religious outgroup",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "Across the surveys, four types of questions appear probing respondents' attitudes toward members of religious outgroups: willingness to have members of different religious groups occupy social roles at varying ``distances'' to the respondent---as neighbors, work associates, friends, citizens, or family members---as well as trust, favoribility, and discomfort with respect to members of other religious groups. I recode responses dichotomously such that one always indicates that the respondent offered an intolerant attitude toward the religious group specified in the question wording, and zero indicates that the respondent offered a tolerant or neutral/indifferent attitude. All question-specific recodes are listed in SI Appendix, Table \\ref{tab:app_questionsrecodes}. Only responses for which the question inquired about a religion that was different from the religion with which the respondent identified are included in the dataset; this ensures that the dataset only captures attitudes toward religious outgroups.",       
       
    
       "Individual/question-item outcomes",
       "$\\bullet$ Generalized social distrust",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "I focus on the question: ``Generally speaking, would you say that most people can be trusted or that you need to be very careful in dealing with people?'' This question---or variants of it---is available in most, but not all, survey instruments. I recode responses dichotomously such that one always indicates that the respondent offered a negative attitude (i.e. expressed generalized distrust in other people), and zero indicates that the respondent offered a positive or neutral/indifferent attitude.",   
  
 
       "Individual/question-item outcomes",
       "$\\bullet$ Religiosity",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "Surveys probe the strength of individuals' personal religiosity in three ways: (i) by asking whether---or to what extent---the respondent considers themself to be ``a religious person''; (ii) by asking how important religion is in the respondent's life; and (iii) by asking about the frequency with which a respondent engages in religious practices (praying, attending religious services). I employ one measure of religiosity per respondent. Where surveys contain more than one type of measure, I use type (i) if available, or otherwise types (ii) or (iii) in that order of preference. Most surveys provide likert-style response options (e.g. 1 = Not at all important, 2 = Somewhat unimportant, 3 = Somewhat important, 4 = Very important). For simplicity, I assume equal differences between ordered categories, and rescale variables to take a value between zero and one, where zero indicates ``not at all religious'' and one indicates ``very religious.''",
      
 
       "Individual/question-item outcomes",
       "$\\bullet$ Resp. reports having any religion",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "This variable takes one if a respondent reported subscribing to any religion; it takes zero if the respondent reported being not religious (including if they reported being athiest or agnostic), or if they replied ``don't know,'' ``can't say,'' or refused to answer the question, or if the value for this variable is missing in the dataset for any other reason.",      
      
 
       "Individual/question-item outcomes",
       "$\\bullet$ Non-response to religious intolerance question",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "This variable takes one if a respondent offered a substantive response to a question about their attitude toward religious outgroups; it takes zero if the respondent replied ``don't know,'' ``can't say,'' or refused to answer the question, or if the value for this variable is missing in the dataset for any other reason.",
      
 
       "Individual treatments",
       "$\\bullet$ Surveyed [X] months before and/or after an election",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}. National Elections Across Democracy and Autocracy (NELDA) dataset; bit.ly/3Ng5YJo.",
       "The dates on which individual respondents were interviewed are drawn from the original survey data. In instances where respondent-specific dates are not available, I input the individual's survey date as the midpoint of the range of dates during which surveys were fielded in that country/round; this information is provided in the surveys' technical documentation. For every individual, I then generate columns that contain the dates of the most recent (completed) and next upcoming national elections occuring in the country where the survey took place. Election dates are from the NELDA dataset. With this information merged, I then compute columns for (a) the number of days elapsed between the last election and the date on which the respondent was interviewed, and (b) the number of days between the date on which the respondent was interviewed and the next (forthcoming) election. Finally, I compute the suite of treatment indicators, dichotomously recording whether an individual's survey date falls within a given time window---variously specified as three, six, or nine months---of a previous and/or forthcoming election.",
  
 
       "Individual treatments",
       "$\\bullet$ Percentage way through election cycle surveyed",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}. National Elections Across Democracy and Autocracy (NELDA) dataset; bit.ly/3Ng5YJo.",
       "For each individual, this continuous measure is computed as: (Number of days since last election)/(Total number of days between next election and last election). See the previous row of this table for a desciption of how the component variables were derived.",  

 
       "Individual characteristics",
       "$\\bullet$ Female",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "The variable takes one if the respondent identifies as female and zero otherwise (unless missing). This information is available in almost all surveys.",
  

       "Individual characteristics",
       "$\\bullet$ Rural",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "Most survey datasets contain a variable that captures the enumerator's assessment of the type of settlement where the interview took place. To standardize across instruments, I generate a dichotomous indicator for ``Rural.'' This takes one in the following cases (and zero otherwise): (i) the terms ``rural,'' ``country,'' ``countryside,'' or ``village'' are used to describe the interview location; (ii) 10,000 people or fewer are reported as living in the settlement; (iii) in cases where the binned response-options do not include the number 10,000 for the population of the settlement, then the population-bin  with the upper bound above and closest to 10,000 is considered ``rural.'' Settlements described as ``refugee camps'' are coded as not being rural.", 
  

       "Individual characteristics",
       "$\\bullet$ Education",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "Surveys record individuals' educational attainment in a plethora of ways. I assign each respondent to one of three educational attainment categories, which can be discerned quite consistently across datasets. I code individuals as having ``No education'' if they did not complete a country's formal primary school curriculum (noting that the length of the formal curriculum varies across countries); where that information in not provided, I code individuals with fewer than 5 years (grades) of formal education as having ``No education.'' Individuals who report having completed an academic (not vocational) bachelors/undergraduate degree, or a more advanced academic degree, are recorded as having attained a ``College'' education; where only number of years of education is provided, I code individuals with 15 or more years of education as having a ``College'' education also. All remaining individuals---those who completed a primary school education but did not complete a college education, under these defintions---are coded has having ``Primary'' education, meaning that this group's educational attainment ranges from completed primary education up to and including incomplete college education. Each category receives a dichotomous indicator in the dataset.",
  
       
       "Individual characteristics",
       "$\\bullet$ Age",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "Most surveys provide either respondents' precise age (in years), or their year of birth (from which age can be computed by knowing the year of the survey). Where surveys provide only a categorical age range (e.g. ``27-35''), individuals' recoded age is imputed as the midpoint of the given range (thus, 31 in the ``27-35'' example). Where surveys provide categories that lack either an upper or lower bound (e.g. ``75 and older,'' ``20 or younger''), individuals' age is imputed as the \\textit{given} bound (thus, 75 and 20, respectively, in the examples just cited).", 

 
       "Individual characteristics",
       "$\\bullet$ Member of largest religion",
       "Cross-National Socio-Economic and Religion (CNSER) Data, 2011; bit.ly/3zmGXIm.",
       "I use the RELRECOD variable from the CNSER data to code the largest religion for each country as Christian, Muslim, Jewish, Hindu, Buddhist, Shinto, or Other religion. I then create an indicator that takes one (and zero otherwise) in cases where a surveyed individual's self-identified religion matches the largest religion in the country where they reside.", 
  
  
       "Individual characteristics",
       "$\\bullet$ Surveyed in person",
       "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
       "Technical survey documentation and, in several cases, dataset variables were used to create an indicator that takes one if the respondent was interviewed face-to-face, in-person by an enumerator, and zero otherwise.", 
  

       "Country/election-level characteristics",
       "$\\bullet$ Regime: Democracy, Autocracy",
       "Varietes of Democracy (V-DEM) Project, version 12; bit.ly/3NcHP6t.",
       "Variable derived from the V-DEM item, v2xregime: ``How can the political regime overall be classified considering the competitiveness of access to power (polyarchy) as well as liberal principles?'' The original V-DEM variable is coded for country/years and takes four levels. In my recode, I class ``Autocracy'' as comprising either the level ``Closed autocracy'' or ``Electoral autocracy'' in the original coding scheme, and ``Democracy'' as comprising either ``Electoral democracy'' or ``Liberal democracy'' in the original coding scheme.",

 
       "Country/election-level characteristics",
       "$\\bullet$ Electoral system: Plurality, P.R.",
       "Database of Political Institutions (DPI) 2020; bit.ly/3Tn5JiM.",
       "I use the variable HOUSESYS from the DPI dataset, which codes the electoral rule (proportional representation or plurality) governing the election of the majority of national ``house seats'' in a given country/year. I generate a variable that takes one if the value of HOUSESYS is ``Plurality'' for a given country/year, and zero otherwise. I generate a second variable that takes one if the value of HOUSESYS is ``Proportional representation (P.R.)'' for a given country/year, and zero otherwise.", 
      
      
       "Country/election-level characteristics",
       "$\\bullet$ Federalism",
       "Database of Political Institutions (DPI) 2020; bit.ly/3Tn5JiM.",
       "I use the variable STATE from the DPI dataset, which codes whether state/provincil governments are locally elected or not for a given country/year. I generate a variable that takes zero if the value of STATE is zero (denoting that state/provincial governments are not elected), and one if the value of STATE is one or two (respectively denoting that the state/provincial legislature, or the state/provincial executive and legislature, are elected).",


       "Country/election-level characteristics",
       "$\\bullet$ Religious party in national assembly",
       "Varieties of Party Identity and Organization (V-Party) Dataset; bit.ly/3MbpGVt.",
       "The V-Party dataset consists of expert codings of the characteristics of parties attaining more than five percent of seats in a country's national assembly. The original unit of analysis is the country/election year/party. I use the variable, v2parelig: ``To what extent does this party invoke God, religion, or sacred/religious texts to justify its positions?'' I classify a religious party as one that is coded as ``Always or almost always'' or ``Often, but not always'' invoking God, religion, or sacred/religious texts to justify its positions. Finally, I generate a variable that takes one if there is any religious party in the national assembly in a given country/election year (and zero otherwise). To make a country/year panel, I fill this variable forward annually within country, until the next election is reached.",
  

       "Country/election-level characteristics",
       "$\\bullet$ Last election competitive",
       "National Elections Across Democracy and Autocracy (NELDA) dataset; bit.ly/3Ng5YJo.",
       "Variable based on NELDA 12, which is dichotomous: ``Was the incumbent or ruling party confident of victory before elections?'' In the original dataset, ``no'' indicates that the incumbent was not confident of victory, indicating that the election was at least somewhat competitive. The final analysis variable takes one if the last election was coded as competitive according to this measure, and zero otherwise.",

      
       "Country/election-level characteristics",
       "$\\bullet$ Religious conflict history",
       "Religion and Armed Conflict (RELAC) Data; bit.ly/3nh49kk.",
       "The RELAC dataset is an extension of the UCDP Dyadic Dataset of armed conflicts in the world between 1975 and 2015. Armed conflicts are defined as: ``a contested incompatibility that concerns government and/or territory where the use of armed force between two parties, of which at least one is the government of a state, results in at least 25 battle-related deaths in a calendar year.'' RELAC adds a newly coded column (RelIncomp) for ``Religious Incompatability,'' capturing ``whether there is a religious dimension in the original incompatibility as explicitly stated at the onset of the conflict by the representatives of the primary parties.'' The dataset also provides a variable for the start date of each conflict. I keep all conflicts for which RelIncomp takes a value of one. Finally, in the analysis dataset, I generate a dichotomous variable indicating whether, at the time of the last election (in relation to when the respondent was surveyed), a country had previously experienced a religious conflict according to the RELAC dataset. Note, therefore, that this measure does not capture any conflicts that occurred prior to 1975.",
       

       "Country/election-level characteristics",
       "$\\bullet$ On-cycle elections",
       "National Elections Across Democracy and Autocracy (NELDA) dataset; bit.ly/3Ng5YJo.",
       "Variable based on NELDA 6, which is dichotomous: ``If regular, were these elections early or late relative to the date they were supposed to be held per established procedure?'' In the original dataset, ``no'' indicates that the election was held on-cycle. The final analysis variable takes one if both the last and next elections (relative to the date of the individual survey) were held on-cycle, and zero otherwise.",
  
      
       "Country/election-level characteristics",
       "$\\bullet$ GDP per capita above median",
       "United Nations Statistics Division; bit.ly/3ze9Pm8",
       "The UN provides a dataset of GDP per capita---at current prices in US Dollars---for all countries except Taiwan between 1970 and 2020. I limit the series to the years 1975 to 2020, which is the date-range of the first to last election that appears in the analysis dataset. For each year, I then categorize each country as above or below the median per-capita income for all countries in that given year.",
  
      
       "Country/election-level characteristics",
       "$\\bullet$ Election involved civilian deaths",
       "National Elections Across Democracy and Autocracy (NELDA) dataset; bit.ly/3Ng5YJo.",
       "Variable based on NELDA 33, which is dichotomous: ``Was there significant violence involving civilian deaths immediately before, during, or after the election?'' The analysis variable takes one if there was such violence and zero otherwise.", 
      

      "Country-level characteristics",
      "$\\bullet$ Mean intolerance tercile",
      "Compiled multi-national surveys; see SI Appendix, Table \\ref{tab:includedsurveys}.",
      "I take the average rate of religious intolerance toward religious outgroups by country, using the integrated survey dataset, across all available years. I then assign countries into terciles of intolerance using the ranking of these country-level averages.",
      
      
      "Country-level characteristics",
      "$\\bullet$ Religious fractionalization above median",
      "Composition of Religious and Ethnic Groups Fractionalization/Polarization Estimates dataset, produced by Steven V. Miller; bit.ly/3grYjfy.",
      "I use the religious fractionalization measure from the Steven V. Miller dataset. The measure is an application of the Herfindahl-Hirschman concentration index, based on cross-national religious demographic data for the year 2000. I use the median value for the full set of countries to create a dichotomous varaible indicating that a country's value was above median.",


      "Country-level characteristics",
      "$\\bullet$ Religious polarization above median",
      "Composition of Religious and Ethnic Groups Fractionalization/Polarization Estimates dataset, produced by Steven V. Miller; bit.ly/3grYjfy.",
      "I use the religious polarization measure from the Steven V. Miller dataset dataset. The measure is an application of the Montalvo and Reynal-Querol polarization index, introduced in Jose Montalvo and Marta Reynal-Querol (2005), ``Ethnic polarization, potential conflict, and civil wars,'' American Economic Review 95(3), pp. 796--816. The calculation is based on cross-national religious demographic data for the year 2000. I use the median value for the full set of countries to create a dichotomous varaible indicating that a country's value was above median.",
      
      
      "Country-level characteristics",
      "$\\bullet$ Linguistic fractionalization above median",
      "Alberto Alesina et al (2003). ``Fractionalization.'' Journal of Economic Growth 8, pp. 155–194; bit.ly/3bl0Rtr.",
      "I use the linguistic fractionalization measure from the original Alesina et al dataset. The measure is an application of the Herfindahl concentration index, based on data from various sources. I use the median value for the full set of countries to partition the data into above and below median values.",
      
      
       "Country-level characteristics",
       "$\\bullet$ Ethnic fractionalization above median",
       "Alberto Alesina et al (2003). ``Fractionalization.'' Journal of Economic Growth 8, pp. 155–194; bit.ly/3bl0Rtr.",
       "I use the ethnic fractionalization measure from the original Alesina et al dataset. The measure is an application of the Herfindahl concentration index, based on data from various sources. I use the median value for the full set of countries to partition the data into above and below median values.",


       "Fixed effects",
       "$\\bullet$ Country",
       "",
       "Fixed effects for each country.",
  

       "Fixed effects",
       "$\\bullet$ Question-type",
       "",
       "Fixed effects for the question types that describe the nature of the question asked regarding religious intolerance (various social roles, trust, favorability, discomfort).",
  
 
       "Fixed effects",
       "$\\bullet$ Question-target",
       "",
       "Fixed effects for the religion or sect specified in the question text for questions about religious intolerance, including for aggregate target groups such as ``Different religion'' and ``Different sect.''")

# print table
  out %>%
    select(-group) %>% 
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Variable",
            "Data source(s)",
            "Description"),
            align = "l"),
          caption = "\\label{tab:app_vardesc}Variables description and sources.",
          linesep = "\\addlinespace") %>%
    kable_styling(font_size = 8.5,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) Variables description and sources.",
                  repeat_header_method = "replace") %>%
    column_spec(1, width = "12em") %>%
    column_spec(2, width = "11em") %>% 
    column_spec(3, width = "26em") %>% 
    pack_rows(index = table(fct_inorder(out$group)), underline = T, latex_gap_space = "0.5cm")
```

\clearpage

<!-- full balance table -->

```{r results="asis"}
# balance estimation function
  # this is necessary to ensure custom weights are applied, accounting for differential missingness across outcomes

  balance_fun <-
    function(iv = NULL,
             outcome = NULL) {

    df <- 
      analysis_df_outgroups %>%
      filter(resp_interview_start_end_date_range < 182) %>% 
      distinct(resp_id, .keep_all = T) %>% 
      filter(!is.na(get(outcome)) & !is.na(get(iv))) %>% 
      group_by(country_election_cycle_id) %>%
         mutate(weight = 1/n()) %>%
      ungroup()
    
    frm <- 
      as.formula(paste0(outcome, " ~", iv))
  
    model <- 
      feols(
          frm, 
          fixef = c("resp_country_common", "qinfo_type", "qinfo_target"), #fixed effects 
          cluster = ~country_election_cycle_id,
          weights = df$weight,
          data = df,
          lean = T)

  f1 <- function(x) format(round(x, 2), nsmall = 2)
  f2 <- function(x) format(round(x, 0), big.mark=",")  
    
  formatted <- 
    modelsummary(
      model, 
      stars = c("*" = 0.1, "**" = 0.05, "***" = 0.01),
            gof_map =
              tribble(
                ~raw, ~clean, ~fmt, ~omit,
                "nobs", "$N$", f2, F,
                "r.squared", "$R^2$", f1, F,
                "FE: resp_country_common", "Country FE", ~fmt, F),
      output = "data.frame") %>% 
    mutate(across(starts_with('Model'), ~ifelse(.=="X" & term == "Country FE", "Y",.)),
           term = ifelse(statistic == "modelsummary_tmp2", "", term),
           treat = iv) %>%
    select(matches("term|Model"))     
      
    }
  
# declare balance outcomes to map over    
  args <- 
    as_tibble(
      expand.grid(
        iv = c(
          "x_within_3_months_pre_election",
          "x_within_6_months_pre_election",
          "x_within_9_months_pre_election",
          
          "x_within_3_months_post_election",
          "x_within_6_months_post_election",
          "x_within_9_months_post_election",

          "x_within_3_months_pre_post_election",
          "x_within_6_months_pre_post_election",
          "x_within_9_months_pre_post_election"),
        outcome = c(
          "resp_female",
          "resp_age_recode",
          "resp_rural",
          "resp_member_largest_religion",
          "resp_edu_1_noedu",
          "resp_edu_2_primary_to_college",
          "resp_edu_3_college",
          "resp_surveyed_in_person")
        )) %>% 
    mutate(across(everything(), as.character))

# switch for running balance models
  if(isTRUE(balance_from_scratch)) {
  # run models  
    res <- 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_3_months_pre_election"), .f = balance_fun)) %>% 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_6_months_pre_election"), .f = balance_fun)) %>% 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_9_months_pre_election"), .f = balance_fun)) %>% 

      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_3_months_post_election"), .f = balance_fun)) %>% 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_6_months_post_election"), .f = balance_fun)) %>% 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_9_months_post_election"), .f = balance_fun)) %>% 

      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_3_months_pre_post_election"), .f = balance_fun)) %>% 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_6_months_pre_post_election"), .f = balance_fun)) %>% 
      bind_rows(pmap_dfc(args %>% filter(iv == "x_within_9_months_pre_post_election"), .f = balance_fun))
            
    saveRDS(res, "_temp_res/res_balance.rds") 
    
  }

# read in balance dataframe
  res <- 
    readRDS("_temp_res/res_balance.rds")
  
# format  
  out <- 
    res %>% 
    clean_names() %>% 
    mutate(term_1 = ifelse(term_1 == "Country FE", "Country + Q-type + Q-target FE", term_1)) %>% 
    select(term_1, contains("model")) %>% 
    mutate(treat = ifelse(str_detect(term_1, "months"), term_1, NA)) %>% 
    fill(treat) %>% 
    #mutate(across(everything(), ~ifelse(str_detect(term_1, "months"), paste("\\vspace{0.5}", .), .))) %>% 
    mutate(
      term_1 = 
        dplyr::recode(term_1,
          "x_within_3_months_pre_election" = "Surveyed <3 months pre-election",
          "x_within_6_months_pre_election" = "Surveyed <6 months pre-election",
          "x_within_9_months_pre_election" = "Surveyed <9 months pre-election",
          
          "x_within_3_months_post_election" = "Surveyed <3 months post-election",
          "x_within_6_months_post_election" = "Surveyed <6 months post-election",
          "x_within_9_months_post_election" = "Surveyed <9 months post-election",
          
          "x_within_3_months_pre_post_election" = "Surveyed <3 months pre/post-election",
          "x_within_6_months_pre_post_election" = "Surveyed <6 months pre/post-election",
          "x_within_9_months_pre_post_election" = "Surveyed <9 months pre/post-election"),
      group_lab = 
        dplyr::recode(treat,
          "x_within_3_months_pre_election" = "Panel A",
          "x_within_6_months_pre_election" = "Panel B",
          "x_within_9_months_pre_election" = "Panel C",
          "x_within_3_months_post_election" = "Panel D",
          "x_within_6_months_post_election" = "Panel E",
          "x_within_9_months_post_election" = "Panel F",
          "x_within_3_months_pre_post_election" = "Panel G",
          "x_within_6_months_pre_post_election" = "Panel H",
          "x_within_9_months_pre_post_election" = "Panel I"))
  
# caption  
  cap <- 
    "\\label{tab:app_fullbalance}Weighted least-squares regression estimates of balance on individuals' pre-treatment characteristics. The unit of analysis is the respondent. Q-type and Q-target refer to question-type and question-target, respectively. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. Robust standard errors clustered by country/election cycle are in parentheses."
  
# print 
 out %>%
    select(-c(treat, group_lab)) %>% 
    kable("latex", 
        booktabs = T, 
        escape = F,
        align = c("l", rep("c", 8)),
        col.names = linebreak(c("\\textit{Outcome:}\n\n\n", 
                                "\nFemale\n(1)", 
                                "\nAge\n(2)",
                                "\nRural\n(3)", 
                                "Belongs to\nlargest religion\n(4)", 
                                "Education:\nNone\n(5)", 
                                "Education:\nPrimary\n(6)", 
                                "Education:\nCollege\n(7)",
                                "Surveyed\nin person\n(8)"), c("l", rep("c", 8))),
        caption = cap,
        linesep = "") %>% 
    kable_styling(
      font_size = 6.5,
      latex_options = "hold_position") %>% 
    pack_rows(index = table(out$group_lab), hline_before = T) %>%
    footnote(general = c("*p<0.1; **p<0.05; ***p<0.01"),
         footnote_as_chunk = TRUE, 
         general_title = "",
         escape = F)
```

<!-- estimation inputting pre- and post- variables jointly -->

```{r}
# estimation function
  joint_est_fun <-
    function(iv1 = NULL,
             iv2 = NULL,
             panel_name = NULL) {

  # subset to obs with certain date range
    df <- 
      analysis_df_outgroups %>% 
      filter(
        resp_interview_start_end_date_range < 182 &
        !is.na(eval(str2expression(iv1))) & 
        !is.na(eval(str2expression(iv2))) & 
        !is.na(resp_soc_dist_bin_recode))

  # generate weights
    df <- 
      df %>%
      group_by(country_election_cycle_id) %>%
         mutate(weight = 1/n()) %>%
      ungroup()

  # main model  
    models <-        
      feols(
        as.formula(paste(
          "resp_soc_dist_bin_recode ~", iv1, "+", iv2, "|", 
            "sw(resp_country_common, 
                resp_country_common + qinfo_type, 
                resp_country_common + qinfo_type + qinfo_target)")), 
        cluster = ~country_election_cycle_id, 
        weights = df$weight,
        data = df,
        lean = T)    
    
# formatting functions  
  f1 <- function(x) format(round(x, 2), nsmall = 2)
  f2 <- function(x) format(round(x, 0), big.mark=",")  
    
# format
  formatted <-     
    modelsummary(
        models, 
        stars = c("*" = 0.1, "**" = 0.05, "***" = 0.01),
        coef_map = c(
          "x_within_3_months_pre_election" = "Surveyed <3m pre-election",
          "x_within_6_months_pre_election" = "Surveyed <6m pre-election",
          "x_within_9_months_pre_election" = "Surveyed <9m pre-election",
          
          "x_within_3_months_post_election" = "Surveyed <3m post-election",
          "x_within_6_months_post_election" = "Surveyed <6m post-election",
          "x_within_9_months_post_election" = "Surveyed <9m post-election"),
              gof_map =
                tribble(
                  ~raw, ~clean, ~fmt, ~omit,
                  "nobs", "$N$", f2, F,
                  "r.squared", "$R^2$", f1, F),
        output = "data.frame") %>% 
    clean_names() %>%
    mutate(
      term = 
        case_when(
          statistic == "modelsummary_tmp2" ~ "",
          TRUE ~ term),
      m = panel_name) %>% 
    select(-c(part, statistic))
    
    # clean up
      rm(df)
      return(formatted)
          
    }

# output
  out <- 
    bind_rows(joint_est_fun(
      iv1 = "x_within_3_months_pre_election", 
      iv2 = "x_within_3_months_post_election",
      panel_name = "Panel A: Treatment window = 3 months")) %>% 
    bind_rows(joint_est_fun(
      iv1 = "x_within_6_months_pre_election", 
      iv2 = "x_within_6_months_post_election",
      panel_name = "Panel B: Treatment window = 6 months")) %>% 
    bind_rows(joint_est_fun(
      iv1 = "x_within_9_months_pre_election", 
      iv2 = "x_within_9_months_post_election",
      panel_name = "Panel C: Treatment window = 9 months"))
  
# caption
  cap <- 
    "\\label{tab:app_jointest}Weighted least-squares regression estimates of the relationship between being surveyed within specified time-frames before and after a national election and expressions of intolerance toward religious outgroups. This table presents the results of nine separate regression models. Indicators for being surveyed before and after an election are entered simultaneously into the regression models. To assess robustness, different combinations of fixed effects are included, as indicated in the table header. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. In each model, observations are weighted such that each country/election cycle contributes equally in estimation. Robust standard errors clustered by country/election cycle are in parentheses."    
  
# print table 
  out %>%
    select(-c(m)) %>% 
    kable("latex", 
        booktabs = T, 
        escape = F,
        align = c("l", rep("c", 3)),
        col.names = linebreak(c("", "(1)", "(2)", "(3)"), align = "c"),
        caption = cap,
        linesep = "") %>% 
    kable_styling(
      font_size = 10,
      latex_options = "hold_position") %>% 
    pack_rows(index = table(out$m)) %>%  
    add_header_above(
      c("Question-target FE:", "N", "N", "Y"),
      line = T, italic = c(T, rep(F, 3)), align = c("l", rep("c", 3))) %>% 
    add_header_above(
      c("Question-type FE:", "N", "Y", "Y"),
      line = F, italic = c(T, rep(F, 3)), align = c("l", rep("c", 3))) %>%   
    add_header_above(
      c("Country FE:", "Y", "Y", "Y"),
      line = F, italic = c(T, rep(F, 3)), align = c("l", rep("c", 3))) %>% 
    footnote(general = c("*p<0.1; **p<0.05; ***p<0.01"),
         footnote_as_chunk = TRUE, 
         general_title = "",
         escape = F)  
  
# # sanity check
#   library(lfe)
# 
#   df <-
#     analysis_df_outgroups %>%
#     filter(resp_interview_start_end_date_range < 182) %>%
#     filter(
#       !is.na(x_within_6_months_pre_election) &
#       !is.na(x_within_6_months_post_election) &
#       !is.na(resp_soc_dist_bin_recode)) %>% 
#     group_by(country_election_cycle_id) %>%
#        mutate(weight = 1/n()) %>%
#     ungroup()
# 
#   summary(felm(resp_soc_dist_bin_recode ~ x_within_6_months_pre_election + x_within_6_months_post_election | resp_country_common + qinfo_type + qinfo_target | 0 | country_election_cycle_id, data = df, weights = df$weight))
```

\clearpage

<!-- tabulated main results -->

```{r}
# tidy
  rm(df)

# declare arguments
  args <- 
    labeling %>% 
    select(iv = var_name)

# run models
  out <- 
    pmap_dfr(args, .f = main_est_fun)

# clean
  formatted <- 
    out %>% 
    mutate_at(c("estimate", "p.value", "conf.low", "conf.high", "std.error"), ~format(round(., 3), nsmall = 3)) %>% 
    mutate(conf_int = paste0("(", conf.low, ", ", conf.high, ")")) %>% 
    mutate(
      fulllabel = 
        dplyr::recode(term,
          "x_within_3_months_pre_election" = "Surveyed <3 months pre-election",
          "x_within_6_months_pre_election" = "Surveyed <6 months pre-election",
          "x_within_9_months_pre_election" = "Surveyed <9 months pre-election",
          
          "x_within_3_months_post_election" = "Surveyed <3 months post-election",
          "x_within_6_months_post_election" = "Surveyed <6 months post-election",
          "x_within_9_months_post_election" = "Surveyed <9 months post-election",
          
          "x_within_3_months_pre_post_election" = "Surveyed <3 months pre-/post-election",
          "x_within_6_months_pre_post_election" = "Surveyed <6 months pre-/post-election",
          "x_within_9_months_pre_post_election" = "Surveyed <9 months pre-/post-election")) %>% 
    select(
      fulllabel,
      estimate,
      std.error,
      conf_int,
      p.value,
      significance,
      nobs,
      n_clusters) %>% 
    mutate(
    nobs = format(nobs, big.mark=","))

# print table
  formatted %>%
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Treatment",
            "Estimate",
            "S.E.",
            "C.I.",
            "p-value",
            "Sig.",
            "N",
            "Countries")),
            align = c(rep("l", 1), rep("c", 7)),
          caption = "\\label{tab:app_tabmainres}Tabulation of primary results displayed in Figure \\ref{fig:main_mainres} of the main paper. Weighted least-squares regression estimates of the relationship between being surveyed within a specified time-frame before and/or after a national election and expressions of intolerance toward religious outgroups. The unit of analysis is the respondent/question-item. Models include country, question-type, and question-target fixed effects. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. Standard errors are clustered by country/election cycle, and 95 percent confidence intervals are based on these.",
          linesep = "") %>%
    kable_styling(font_size = 9,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) Primary results.",
                  repeat_header_method = "replace") %>% 
   footnote(general = c("*p<0.1; **p<0.05; ***p<0.01"),
      footnote_as_chunk = TRUE, 
      general_title = "",
      escape = F)
```

\clearpage

<!-- tabulated heterogeneous effects -->

```{r}
# clean
  out <- 
    het_res %>% 
    mutate_at(c("estimate", "p.value", "conf.low", "conf.high", "std.error"), ~format(round(., 3), nsmall = 3)) %>% 
    mutate(conf_int = paste0("(", conf.low, ", ", conf.high, ")")) %>% 
    mutate(significance =
                 case_when(
                   p.value >= 0.05 & p.value < 0.1 ~ "*",
                   p.value >= 0.01 & p.value < 0.05 ~ "**",
                   p.value < 0.01 ~ "***",
                   TRUE ~ "")) %>%   
    filter(term == "x_within_6_months_pre_election") %>% 
    select(
      group_label,
      subgroup_label,
      estimate,
      std.error,
      conf_int,
      p.value,
      significance,
      nobs,
      n_clusters) %>% 
    mutate(
    nobs = format(nobs, big.mark=","))

# print table
  out %>%
    select(-group_label) %>% 
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Subgroup",
            "Estimate",
            "S.E.",
            "C.I.",
            "p-value",
            "Sig.",
            "N",
            "Countries")),
            align = c(rep("l", 1), rep("c", 7)),
          caption = "\\label{tab:app_htetabbed}Tabulation of subgroup effects displayed in Figure 3 of the main paper. Weighted least-squares regression estimates of the relationship between being surveyed six months before a national election and expressions of intolerance toward religious outgroups. Models include country, question-type, and question-target fixed effects. The unit of analysis is the respondent/question-item. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. Standard errors are clustered by country/election cycle, and 95 percent confidence intervals are based on these.",
          linesep = "") %>%
    pack_rows(index = table(fct_inorder(out$group_label))) %>%
    kable_styling(font_size = 8,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) HTEs.",
                  repeat_header_method = "replace") %>% 
   footnote(general = c("*p<0.1; **p<0.05; ***p<0.01"),
      footnote_as_chunk = TRUE, 
      general_title = "",
      escape = F)
```

\clearpage

```{r}
# htes, 6-month treatment, democracies only
  if(isTRUE(hte_mods_from_scratch)) {

    args <- 
      tribble(
        ~subgroups, ~subgroup_label, ~group_label,

        "nelda_12_competitive_election_LAST == 1", "Yes", "1. Last election competitive",
        "nelda_12_competitive_election_LAST == 0", "No", "1. Last election competitive",
        
        "dpi_housesys_pr == 1", "Plurality", "2. Electoral system",
        "dpi_housesys_plurality == 1", "P.R.", "2. Electoral system",

        "dpi_subnational_govt_elected == 1", "Yes", "3. Federalism",
        "dpi_subnational_govt_elected == 0", "No", "3. Federalism",
                
        "vparty_religious_party_in_nat_assembly == 1", "Yes", "4. Religious party in national assembly",
        "vparty_religious_party_in_nat_assembly == 0", "No", "4. Religious party in national assembly",

        "relac_previous_religious_conflict == 1", "Yes", "5. Religious conflict history",
        "relac_previous_religious_conflict == 0", "No", "5. Religious conflict history",

        "df_prejudice_all_cut == 1", "Least", "6. Mean intolerance tercile",
        "df_prejudice_all_cut == 2", "Medium", "6. Mean intolerance tercile",
        "df_prejudice_all_cut == 3", "Most", "6. Mean intolerance tercile",

        "relfp_relfrac_givenyear_above_median == 1", "Above median", "7. Religious fractionalization",    
        "relfp_relfrac_givenyear_above_median == 0", "Below median", "7. Religious fractionalization",    
  
        "relfp_relpol_givenyear_above_median == 1", "Above median", "8. Religious polarization",    
        "relfp_relpol_givenyear_above_median == 0", "Below median", "8. Religious polarization",  

        "nelda_last_and_next_election_oncycle == 1", "Yes", "9. On-cycle elections",
        "nelda_last_and_next_election_oncycle == 0", "No", "9. On-cycle elections",
        
        "un_gdppd_2022_prices_above_median_for_given_year == 1", "Above median", "10. GDP per capita",
        "un_gdppd_2022_prices_above_median_for_given_year == 0", "Below median", "10. GDP per capita",
  
        "resp_member_largest_religion == 1", "Yes", "11. Resp. belongs to largest religion",
        "resp_member_largest_religion == 0", "No", "11. Resp. belongs to largest religion",
        
        "resp_edu_1_noedu == 1", "None", "12. Resp. education",
        "resp_edu_2_primary_to_college == 1", "Primary", "12. Resp. education",
        "resp_edu_3_college == 1", "College", "12. Resp. education") %>% 
      expand_grid(
        iv = c(
          "x_within_6_months_pre_election"),
        democracies_only = c(TRUE))

    het_res_dem_only <- 
      pmap_dfr(args, .f = hte_fun)

  # save
    saveRDS(het_res_dem_only, "_temp_res/het_res_dem_only.rds")  
    
  }

# load hte results
  het_res_dem_only <-
    readRDS("_temp_res/het_res_dem_only.rds")

# clean
  out <- 
    het_res_dem_only %>% 
    mutate_at(c("estimate", "p.value", "conf.low", "conf.high", "std.error"), ~format(round(., 3), nsmall = 3)) %>% 
    mutate(conf_int = paste0("(", conf.low, ", ", conf.high, ")")) %>% 
    mutate(significance =
                 case_when(
                   p.value >= 0.05 & p.value < 0.1 ~ "*",
                   p.value >= 0.01 & p.value < 0.05 ~ "**",
                   p.value < 0.01 ~ "***",
                   TRUE ~ "")) %>%   
    select(
      group_label,
      subgroup_label,
      estimate,
      std.error,
      conf_int,
      p.value,
      significance,
      nobs,
      n_clusters) %>% 
    mutate(
    nobs = format(nobs, big.mark=","))

# print table
  out %>%
    select(-group_label) %>% 
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Subgroup",
            "Estimate",
            "S.E.",
            "C.I.",
            "p-value",
            "Sig.",
            "N",
            "Countries")),
            align = c(rep("l", 1), rep("c", 7)),
          caption = "\\label{tab:app_hte_demonly}Subgroup effects, equivalent to those displayed in Figure 3 of the main paper, but for \\textit{democratic countries only}. Weighted least-squares regression estimates of the relationship between being surveyed six months before a national election and expressions of intolerance toward religious outgroups. Models include country, question-type, and question-target fixed effects. The unit of analysis is the respondent/question-item. Only responses for which the survey date can be accurately pintpointed to within a six-month time bracket are included. Observations are weighted such that each country/election cycle contributes equally in estimation. Standard errors are clustered by country/election cycle, and 95 percent confidence intervals are based on these.",
          linesep = "") %>%
    pack_rows(index = table(fct_inorder(out$group_label))) %>%
    kable_styling(font_size = 9,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) HTEs.",
                  repeat_header_method = "replace") %>% 
   footnote(general = c("*p<0.1; **p<0.05; ***p<0.01"),
      footnote_as_chunk = TRUE, 
      general_title = "",
      escape = F)
```

\clearpage

<!-- description of included original sources -->

```{r}
# sources: original links
  out <- 
    analysis_df_outgroups %>%
    distinct(resp_source, resp_original_data_url) %>% 
    group_by(resp_source) %>% 
      summarise(urls = paste0(unique(resp_original_data_url), collapse = "; ")) %>% 
    ungroup() %>% 
    select(resp_source, urls) %>% 
    arrange(resp_source) %>% 
    mutate(index = row_number())

# brief descriptions of surveys
  desc <- 
    tribble(
      ~index, ~description, ~rep,
      
      1, 
      "``The survey of Muslims was conducted on behalf of Arizona State University by Abt SRBI in Southeast Asia, West Africa, and Western Europe. The goal of the study is to investigate how Muslim individuals and communities respond to and counter radical or extremist actors in their discourses. It details religious attitudes and perceptions of the impact of the West on Muslim societies.''",
      "Muslims only",

      2, 
      "``A pan-African, non-partisan survey research network that conducts public attitude surveys on democracy, governance, the economy, and society ... Our network encompasses more than 30 national partners responsible for data collection, analysis, and in-country dissemination of findings.''",
      "Nationally representative",
      
      3, 
      "``Arab Barometer is a nonpartisan research network that provides insight into the social, political, and economic attitudes and values of ordinary citizens across the Arab world. We have been conducting high quality and reliable public opinion surveys in the Middle East and North Africa since 2006. We are the longest-standing and the largest repository of publicly available data on the views of men and women in the MENA region.''",
      "Nationally representative",
      
      4, 
      "``The Arab Opinion Index [is] an annual survey conducted by the Arab Center in order to gauge Arab public opinion around a number of political, cultural, and social topics. The program is headed by a specialist statistician, leading a team of research assistants and experts in survey methods.''",
      "Nationally representative",
      
      
      5, 
      "``In October 2001, the European Commission launched a new series of surveys in the 13 countries that are applying for European Union membership under the heading Candidate Countries Eurobarometer ... The CCEB surveys gather information from the societies applying to become members of the EU in a way that is comparable with the Standard Eurobarometer.''",
      "Nationally representative",
      
      6, 
      "``The Caucasus Barometer is an annually conducted nationwide survey in Georgia, Armenia and Azerbaijan that covers a wide range of social, economic and political issues in the region.'' It is run by the Caucasus Research Resource Centers.",
      "Nationally representative",
    
      7, 
      "Part of the Middle Eastern Values Study. ``The objective of Middle Eastern Values Studies (MEVS) is to advance the social-scientific understanding of the causes and consequences of the values and the belief systems of the people of the Middle East ... The Middle East Value Studies began with a three-country survey ... in 2000-2001.''",
      "Nationally representative",
      
      8, 
      "Part of the Middle Eastern Values Study. ``The objective of Middle Eastern Values Studies (MEVS) is to advance the social-scientific understanding of the causes and consequences of the values and the belief systems of the people of the Middle East ... The Middle East Value Studies began with a three-country survey ... in 2000-2001.''",
      "Nationally representative",
      
      9, 
      "``CRONOS was designed and implemented alongside ESS Round 8 in 2016, as part of the larger SERISS project. After completing the ESS face-to-face interview, respondents in Estonia, Great Britain and Slovenia 18 or older were invited to participate in six 20-minute online surveys over a time period of twelve months.''",
      "Nationally representative",
      
      10, 
      "``Eurobarometer is a series of public opinion surveys conducted regularly on behalf of the European Commission and other EU Institutions since 1973 ... The Standard Eurobarometer survey series is a cross-national longitudinal study, designed to compare and gauge trends within Member States of the European Union.''",
      "Nationally representative",
      
      11, 
      "``The European Values Study (EVS) is a large-scale, cross-national, repeated cross-sectional survey research programme on basic human values. It provides insights into the ideas, beliefs, preferences, attitudes, values and opinions of citizens all over Europe.''",
      "Nationally representative",
            
      12, 
      "``These comprehensive studies capture youth attitudes, beliefs, and participation in core domains of life, including democracy, politics, governance, and the EU and also include sections devoted to education, employment, religion, family and lifestyles. Each nation used a questionnaire developed in 2005 for Germany’s Shell Youth Studies as a template and made modifications based on their country’s context to ensure relevance to particular intra-national issues.''",
      "Nationally representative of youths aged approximately 15 to 27 (there are small variations in ages sampled across countries)",
            
      13, 
      "``These comprehensive studies capture youth attitudes, beliefs, and participation in core domains of life, including democracy, politics, governance, and the EU and also include sections devoted to education, employment, religion, family and lifestyles. Each nation used a questionnaire developed in 2005 for Germany’s Shell Youth Studies as a template and made modifications based on their country’s context to ensure relevance to particular intra-national issues.''",
      "Nationally representative of youths aged approximately 15 to 27 (there are small variations in ages sampled across countries)",

      14, 
      "``The International Social Survey Programme (ISSP) is a collaboration between different nations conducting surveys covering topics which are useful for social science research ... The results of the surveys provide a cross-national and cross-cultural perspective to individual national studies. By 2021, 58 countries have already taken part in the ISSP.''",
      "Nationally representative",
            
      15, 
      "``Latinobarometro is an annual public opinion survey that involves some 20,000 interviews in 18 Latin American countries, representing more than 600 million inhabitants ... [It] researches the development of democracy and economies as well as societies, using indicators of opinion, attitudes, behaviour and values.''",
      "Nationally representative",
            
      16, 
      "``The European Bank for Reconstruction and Development ... in collaboration with the World Bank, has carried out three such surveys [on `how transition has affected the lives of people in regions, and what their views are on issues such as democracy, the role of the state, and prospects for the future']: one in 2006, one in 2010 and one in 2016. The most recent polled 51,000 households in 34 countries, mainly `transition countries' in central and eastern Europe as well as Turkey and also, for the sake of comparison with more prosperous western neighbours, from Germany and Italy. For the first time, the survey also covered Cyprus and Greece.''",
      "Nationally representative",
            
      17, 
      "``The Perception and Acceptance of Religious Diversity survey is one of the largest representative surveys to date on religious plurality in Europe. It captures the range of attitudes toward Islam and other religions among residents in five European countries. The survey was carried out in 2010 by the Cluster of Excellence `Religion and Politics' of the University of Münster, together with TNS Emnid.''",
      "Nationally representative",
            
      18, 
      "``The Pew Global Attitudes Project is a series of worldwide public opinion surveys encompassing a broad array of subjects ranging from people’s assessments of their own lives to their views about the current state of the world and important issues of the day.''",
      "Nationally representative",
            
      19, 
      "This survey is part of the ``Pew-Templeton Global Religious Future project, which analyzes religious change and its impact on societies around the world ... The survey in Central and Eastern Europe was conducted via face-to-face interviews under the
direction of three research partners ... The survey is based on samples of noninstitutionalized adults ages 18 and older.''",
      "Nationally representative",
            
      20, 
      "``The report was funded by generous grants from The Pew Charitable Trusts and the John Templeton Foundation as part of the Pew-Templeton Global Religious Futures Project, which aims to increase people’s knowledge of religion around the world ... Our survey asked people to describe their religious beliefs and practices. We sought to gauge their knowledge of, and attitudes toward, other faiths.",
      "Nationally representative",
            
      21, 
      "``This report examines the social and political views of Muslims around the world. It is based on public opinion surveys conducted by the Pew Research Center between 2008 and 2012 in a total of 39 countries and territories on three continents: Africa, Asia and Europe.''",
      "Muslims only",
            
      22, 
      "``The end of communism in the East and the immanent economic integration in the West have unleashed forces of nationalism and ethnicity contained for the last 45 years by the exigencies of the Cold War ... The Times Mirror Survey suggests that contradictory forces are pulling Europe in opposite directions ... Our in depth survey of 13,000 European in nine nations and the Republics of Russia, the Ukraine, and Lithuania finds many reasons to be pessimistic about future developments.''",
      "Nationally representative",
            
      23, 
      "The European Union Agency for Fundamental Rights's ``second European Union Minorities and Discrimination Survey (EU-MIDIS II) ... collected information from over 25,500 respondents with different ethnic minority and immigrant backgrounds across all 28 EU Member States.''",
      "Representative of immigrant groups and Roma populations",
        
      24, 
      "``This project intends to explore and explain the values and sociopolitical and cultural attitudes of young Egyptians and Saudis by looking at four general areas of values ... To analyze these four areas researchers conducted face-to-face interviews with 18 to 25 year old youths from Egypt (in the cities of Cairo, Alexandria, and El-Minya) and from Saudi Arabia (in the cities of Jeddah, Riyadh, and Dammam/Khobar). The research was supported by the United States Institute of Peace, the Mellon Foundation, and Eastern Michigan University.''",
      "Representative of youths aged 18 to 25 in certain cities",

      25, 
      "``A global research project that explores people's values and beliefs, how they change over time, and what social and political impact they have. Since 1981 a worldwide network of social scientists have conducted representative national surveys as part of WVS in almost 100 countries.''",
      "Nationally representative")

# merge
  out_combined <- 
    out %>% 
    left_join(desc, by = "index") %>% 
    select(-index)

# print table
  out_combined %>%
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Source",
            "Link to original data",
            "Brief description",
            "Target sample"),
            align = "l"),
          caption = "\\label{tab:includedsurveys}List and description of included survey series.",
          linesep = "\\addlinespace") %>%
    kable_styling(font_size = 7,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) List and description of included survey series.",
                  repeat_header_method = "replace") %>%
    column_spec(1, width = "10em") %>%
    column_spec(2, width = "10em") %>%
    column_spec(3, width = "30em") %>%
    column_spec(4, width = "7em")
```

\clearpage

```{r}
# generate output
  out <- 
    tribble(
      ~survey, ~reason, ~link,
      "Americas Barometer/LAPOP",	
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3fPLUC4",

      "Arab Public Opinion: A Survey in Six Countries",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3rBzctd",

      "Asia Europe Survey: A Multinational Comparative Study in 18 Countries",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3e8CQrx",

      "Asian Barometer Survey (ABS) [see: EABS]",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3Vcbe5d",

      "Attitudes towards Europe",
      "$\\boldsymbol{\\diamondsuit}$",
      "bit.ly/3MbEV2d",

      "Central and Eastern Eurobarometer",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3yknWVG",

      "Central Asia Barometer",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3ylDXuA",

      "Civicus Civil Society Index",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3SGaELC",

      "East Asia Value Survey",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3EnrcDy",

      "East Asian Social Survey (EASS)",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3Ce57ou",

      "EU Neighborhood Barometer",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3M9I4jj",

      "EUCROSS (The Europeanisation of Everyday Life: Cross-Border Practices and Transnational Identities among EU and Third-Country Citizens)",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3V6f1RI",

      "European Election Studies",
      "$\\boldsymbol{\\heartsuit}$",
      "bit.ly/3V0LVTE",

      "European Quality of Life Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/2T8X5bT",

      "European Social Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3Vcf66f",

      "Gallup World Poll",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3SGaZ0T",

      "Gender And Adolescence: Global Evidence",
      "$\\boldsymbol{\\spadesuit}$ (asked only in Jordan, therefore not multi-national)",
      "bit.ly/3CDDt5B",

      "Generations and Gender Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3ejs1Tg",
      
      "Group‐Focused Enmity in Europe. A Representative Cross‐European Survey on Group‐Focused Enmity and Political Attitudes",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3VcfHVx",

      "Images of the World in the Year 2000",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3Eo8rQK",

      "International Civic and Citizenship Education Study",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3V6Oeoa",

      "INTUNE---Integrated and United? A Quest for Citizenship in an Ever Closer Europe",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3SG3qag",

      "Memory, Youth, Political Legacy And Civic Engagement",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3ebTWoh",

      "Multiple Indicator Cluster Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3RJt4K1",

      "New Baltic Barometer",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3Ce8lZ8",

      "New Departures: Religion and Attitudes toward Church in Eastern (Central) Europe",
      "$\\boldsymbol{\\clubsuit}$",
      "bit.ly/3EoJEfc (link to original survey cannot be found)",

      "New Europe Barometer",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3T0C12x",

      "New Soviet Citizen Surveys",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3V1PQ2J",

      "Pew: Religion in Latin America",
      "$\\boldsymbol{\\spadesuit}$",
      "pewrsr.ch/3MdoAdF",

      "Reader's Digest EURODATA---The Reader's Digest Survey of Europe Today",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3rC050g",

      "Religious Fundamentalism and Radicalization Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3RBzwCV",

      "Social Change in the Baltic Countries",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3SUxXBa",

      "The Voice of the People",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3V1QGMV",

      "Transatlantic Trend Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3CCF8IE",

      "Young Lives Survey",
      "$\\boldsymbol{\\spadesuit}$",
      "bit.ly/3edvq6g")

# print table
  out %>%
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          align = c("l", "c", 'c'),
          col.names = linebreak(c(
            "Source",
            "Reason",
            "Link"), align = c("l", "c", "c")),
          caption = "\\label{tab:excludedsurveys}List of surveys considered but not included, with reason for exclusion. $\\boldsymbol{\\spadesuit}$ indicates that no questions on attitudes toward religious outgroups were asked; $\\boldsymbol{\\clubsuit}$ indicates that digitized microdata are not freely available online; $\\boldsymbol{\\diamondsuit}$ indicates that the surveys were fielded prior to 1980; $\\boldsymbol{\\heartsuit}$ indicates duplicates of others survey datasets.",
          linesep = "\\addlinespace") %>%
    kable_styling(font_size = 7,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) List of surveys considered but not included.",
                  repeat_header_method = "replace") %>%
    column_spec(1, width = "35em") %>%
    column_spec(2, width = "9em") %>%
    column_spec(3, width = "10em")
```

\clearpage

<!-- is survey coverage influenced by how violent/peaceful an election is? -->

```{r}
# clean
  nelda_full_clean <- 
    nelda_full_raw %>%
    filter(
      year(nelda_election_date) > 1982 & # 1982-01-04 is the first date for which we have survey data
      !is.na(nelda_33_any_violence_civilian_deaths) # analysis requires non-missingness on the explanatory variable
      ) %>% 
    select(
      nelda_country_name, 
      nelda_election_date, 
      nelda_33_any_violence_civilian_deaths) %>% 
    mutate(
      # 3 month window
        minus_3_months = nelda_election_date - 91,
        plus_3_months = nelda_election_date + 91,
      
      # 6 month window
        minus_6_months = nelda_election_date - 182,
        plus_6_months = nelda_election_date + 182,

      # 9 month window
        minus_9_months = nelda_election_date - 274,
        plus_9_months = nelda_election_date + 274)
  
# create dataframe of unique dates by country/survey date; count number of responses
  survey_dates <- 
    analysis_df_outgroups %>% 
    group_by(resp_country_common, resp_main_date) %>% 
      summarise(n_responses_on_date = n()) %>% 
    ungroup()
  
# list of elections that had surveys 3 months before or after
  n_resp_by_elec_3m <- 
    nelda_full_clean %>%
    select(starts_with("nelda"), contains("_3_")) %>% 
    left_join(survey_dates, by = c("nelda_country_name" = "resp_country_common")) %>% 
    filter(resp_main_date >= minus_3_months & resp_main_date <= plus_3_months) %>% 
    group_by(nelda_country_name, nelda_election_date) %>%
      summarise(n_responses_3_months = sum(n_responses_on_date),
                survey_dates_3_months = paste0(unique(resp_main_date), collapse = "; ")) %>% 
    ungroup()
  
# list of elections that had surveys 6 months before or after
  n_resp_by_elec_6m <- 
    nelda_full_clean %>%
    select(starts_with("nelda"), contains("_6_")) %>% 
    left_join(survey_dates, by = c("nelda_country_name" = "resp_country_common")) %>% 
    filter(resp_main_date >= minus_6_months & resp_main_date <= plus_6_months) %>% 
    group_by(nelda_country_name, nelda_election_date) %>%
      summarise(n_responses_6_months = sum(n_responses_on_date),
                survey_dates_6_months = paste0(unique(resp_main_date), collapse = "; ")) %>% 
    ungroup()  
  
# list of elections that had surveys 9 months before or after
  n_resp_by_elec_9m <- 
    nelda_full_clean %>%
    select(starts_with("nelda"), contains("_9_")) %>% 
    left_join(survey_dates, by = c("nelda_country_name" = "resp_country_common")) %>% 
    filter(resp_main_date >= minus_9_months & resp_main_date <= plus_9_months) %>% 
    group_by(nelda_country_name, nelda_election_date) %>%
      summarise(n_responses_9_months = sum(n_responses_on_date),
                survey_dates_9_months = paste0(unique(resp_main_date), collapse = "; ")) %>% 
    ungroup()  
  
# final dataset for contested-election-inclusion analysis  
  violent_elec_df <- 
    nelda_full_clean %>% 
    left_join(n_resp_by_elec_3m, by = c("nelda_country_name", "nelda_election_date")) %>%
    left_join(n_resp_by_elec_6m, by = c("nelda_country_name", "nelda_election_date")) %>%
    left_join(n_resp_by_elec_9m, by = c("nelda_country_name", "nelda_election_date")) %>%
    mutate(
      n_responses_3m_pre_post = 
       case_when(
         !is.na(n_responses_3_months) ~ n_responses_3_months,
         TRUE ~ as.integer(0)),
      n_responses_6m_pre_post = 
       case_when(
         !is.na(n_responses_6_months) ~ n_responses_6_months,
         TRUE ~ as.integer(0)),
      n_responses_9m_pre_post = 
       case_when(
         !is.na(n_responses_9_months) ~ n_responses_9_months,
         TRUE ~ as.integer(0)),
      any_survey_3m_pre_post = 
        (n_responses_3m_pre_post > 0)*1,
      any_survey_6m_pre_post = 
        (n_responses_6m_pre_post > 0)*1,
      any_survey_9m_pre_post = 
        (n_responses_9m_pre_post > 0)*1)
```

```{r}
# run regressions
  models <- 
    feols(
      c(any_survey_3m_pre_post,
       any_survey_6m_pre_post,
       any_survey_9m_pre_post,
       n_responses_3m_pre_post,
       n_responses_6m_pre_post,
       n_responses_9m_pre_post)
       ~ nelda_33_any_violence_civilian_deaths,
              fixef = c("nelda_country_name"), 
              cluster = ~nelda_country_name, 
              data = violent_elec_df) 
 
# formatting functions  
  f1 <- function(x) format(round(x, 2), nsmall = 2)
  f2 <- function(x) format(round(x, 0), big.mark=",")  
  
# format
  out <-     
    modelsummary(
        models, 
        stars = c("*" = 0.1, "**" = 0.05, "***" = 0.01),
        coef_map = c(
          "nelda_33_any_violence_civilian_deaths" = "Election involved civilian deaths"
          ),
              gof_map =
                tribble(
                  ~raw, ~clean, ~fmt, ~omit,
                  "nobs", "$N$", f2, F,
                  "r.squared", "$R^2$", f1, F,
                  "FE: nelda_country_name", "Country FE", ~fmt, F),
        output = "data.frame") %>% 
    mutate(across(everything(), ~ifelse(.=="X" & term == "Country FE", "Y",.)),
           term = ifelse(statistic == "modelsummary_tmp2", "", term)) %>% 
    select(-c(part, statistic)) %>% 
    clean_names() 

# declare caption
  cap <- 
    "\\label{tab:app_vltelec}Ordinary least-squares regression estimates of the relationship between survey coverage and whether or not a national election involved civilian deaths. The unit of analysis is the national election. In the table header, ``m'' refers to months. Included in the sample are all national elections from 1982, which is the year of the first survey in this study, to 2020, the end of the NELDA dataset. Standard errors clustered by country are in parentheses."
  
# print regression table  
  out %>%
    kable("latex", 
        booktabs = T, 
        escape = F,
        align = c("l", rep("c", 6)),
        col.names = linebreak(c("", "(1)", "(2)", "(3)", "(4)", "(5)", "(6)"), align = "c"),
        caption = cap,
        linesep = "") %>% 
    kable_styling(
      font_size = 10,
      latex_options = "hold_position") %>% 
    add_header_above(header = c(" " = 1, "...before or after election" = 6)) %>%
    add_header_above(header = c(" " = 1, "3m" = 1, "6m" = 1, "9m" = 1, "3m" = 1, "6m" = 1, "9m" = 1)) %>%
    add_header_above(header = c(" " = 1, "Any survey\nresponses within..." = 3, "Number of survey\nresponses within..." = 3)) %>%    
    footnote(general = c("*p<0.1; **p<0.05; ***p<0.01"),
         footnote_as_chunk = TRUE, 
         general_title = "",
         escape = F)
```

\clearpage

<!-- list of elections employed -->

```{r}
# list of elections by country
  out <- 
    analysis_df_outgroups %>% 
    distinct(resp_country_common, elec_date = last_election) %>% 
    bind_rows(
      analysis_df_outgroups %>% 
      distinct(resp_country_common, elec_date = next_election)) %>% 
    distinct(resp_country_common, elec_date) %>% 
    arrange(resp_country_common, elec_date) %>% 
    filter(!is.na(elec_date)) %>% 
    mutate(elec_date = format(elec_date, "%b %d, %Y"),
           resp_country_common = latexify(resp_country_common, doublebackslash = F)) %>% 
    group_by(resp_country_common) %>% 
      summarise(elec_date = paste0(unique(elec_date), collapse = "; ")) %>% 
    ungroup()

# print table
  out %>%
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Country",
            "National election dates employed in analyses of religious intolerance"),
            align = "l"),
          caption = "\\label{tab:app_eleclist}List of national elections employed in computing treatment indicators for the analysis of attitudes regarding religious intolerance. Note, this is not necessarily a complete list of national elections in each included country; an election's appearance depends on the timing of surveys fielded in a given country.",
          linesep = "\\addlinespace") %>%
    kable_styling(font_size = 6,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) List of national elections employed.",
                  repeat_header_method = "replace") %>%
    column_spec(1, width = "7em") %>%
    column_spec(2, width = "60em")
```

\clearpage

<!-- question-specific information and recodes -->

```{r}
# clean
   out <- 
      analysis_df_outgroups %>% 
      mutate(resp_source_round = paste(resp_source, resp_round)) %>%
      group_by(qinfo_text, qinfo_roptions, qinfo_type) %>%
         summarise(resp_source_round = paste0(unique(resp_source_round), collapse = "; ")) %>% 
      ungroup() %>% 
      select(resp_source_round, qinfo_text, qinfo_roptions, qinfo_type) %>% 
      arrange(resp_source_round) %>% 
      mutate(qinfo_type = str_replace(qinfo_type, "Distance,", "Role:"))

# print table
  out %>%
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Source(s)",
            "Question text",
            "Response options [recodes]",
            "Question-type"),
            align = "l"),
          caption = "\\label{tab:app_questionsrecodes}List of unique question wordings and response-options. Dichotomous recodes for the outcome measure of religious intolerance are indicated by the square brackets in the third column.",
          linesep = "\\addlinespace") %>%
    kable_styling(font_size = 6,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) List of unique question wordings and response-options.",
                  repeat_header_method = "replace") %>%
    column_spec(1, width = "20em") %>%
    column_spec(2, width = "40em") %>%
    column_spec(3, width = "20em") %>%    
    column_spec(4, width = "7em") %>%
    landscape()
```

\clearpage

<!-- list of surveys and coverage by country -->

```{r}
# make dataframe
  out <-
    analysis_df_outgroups %>%
    mutate(resp_source_round = str_trim(paste(resp_source, resp_round))) %>%
    group_by(resp_country_common) %>%
    summarise(
      source_round_list = paste0(unique(resp_source_round), collapse = "; "),
      date_range = 
        case_when(
          year(min(resp_main_date, na.rm = T)) == year(max(resp_main_date, na.rm = T)) ~ as.character(year(min(resp_main_date, na.rm = T))),
          TRUE ~ paste0(year(min(resp_main_date, na.rm = T)), "-", year(max(resp_main_date, na.rm = T)))
        ),
      nobs = sum(!is.na(resp_soc_dist_bin_recode))) %>%
    arrange(resp_country_common) %>%
    ungroup() %>% 
    mutate(resp_country_common = latexify(resp_country_common, doublebackslash = F)) %>% 
    mutate(nobs = format(nobs, big.mark=","))

# print table
  out %>%
    kable("latex",
          booktabs = T,
          escape = F,
          longtable = T,
          col.names = linebreak(c(
            "Country",
            "Source(s)",
            "Range of years covered",
            "N"),
            align = "l"),
          caption = "\\label{tab:app_source_by_text}List of surveys and coverage by country.",
          linesep = "\\addlinespace") %>%
    kable_styling(font_size = 7,
                  latex_options =
                    c("scale_down",
                    "hold_position",
                    "striped",
                    "repeat_header"),
                  repeat_header_text = "(\\textit{continued}) List of surveys and coverage by country.",
                  repeat_header_method = "replace") %>%
    column_spec(1, width = "8em") %>%
    column_spec(2, width = "60em") %>%
    column_spec(3, width = "5em") %>%
    column_spec(4, width = "3em") %>%
    landscape()
```

\clearpage

\section*{Summary data cited in paper}

(Note: this page appears in the output after running the replication code, but not in the published Supplementary Information.)

* Number of observations in the main analysis dataset (`analysis_df_outgroups`): `r nrow(analysis_df_outgroups)`
* Number of unique respondents in the main analysis dataset (`analysis_df_outgroups`): `r length(unique(analysis_df_outgroups$resp_id))`
* Number of countries in the dataset (`analysis_df_outgroups`): `r length(unique(analysis_df_outgroups$resp_country_common))`
* Number of unique country-surveys in the main analysis dataset (`analysis_df_outgroups`): `r analysis_df_outgroups %>% distinct(resp_country_common, resp_source, resp_round) %>% nrow()`
* Years covered by the main analysis dataset (`analysis_df_outgroups`): `r range(year(analysis_df_outgroups$resp_main_date))`
* Proportion of unique respondents in `analysis_df_outgroups` for whom I have the exact survey date: `r analysis_df_outgroups %>% distinct(resp_id, .keep_all = T) %>% mutate(has_ind_date = (!is.na(resp_interview_date))*1) %>% pull(has_ind_date) %>% mean()`
* Median range of survey dates (number of days) for respondents for whom I lack the exact survey date `r analysis_df_outgroups %>% distinct(resp_id, .keep_all = T) %>% mutate(has_ind_date = (!is.na(resp_interview_date))*1) %>% filter(has_ind_date == 0) %>% pull(resp_interview_start_end_date_range) %>% median()`
* Percent of unique respondents in `analysis_df_outgroups` that were interviewed in-person: `r analysis_df_outgroups %>% distinct(resp_id, .keep_all = T) %>% pull(resp_surveyed_in_person) %>% mean(na.rm = T)`
* DALP, mean national vote share secured by parties dependent on various forms of religious mobilization 1: `r dalp_out %>% filter(str_detect(name, "^\\(a\\)")) %>% pull(outcome) %>% mean()`
* DALP, mean national vote share secured by parties dependent on various forms of religious mobilization 2: `r dalp_out %>% filter(str_detect(name, "^\\(b\\)")) %>% pull(outcome) %>% mean()`
* DALP, mean national vote share secured by parties dependent on various forms of religious mobilization 3: `r dalp_out %>% filter(str_detect(name, "^\\(b\\)")) %>% pull(outcome) %>% mean()`
